Move the resources of each renderer to its subdirectory.
We've previously done that for the ngl renderer, but it
is better to be consistent and do it for all the renderers.
'''
for f in gl_source_shaders:
- xml += ' <file alias=\'gl/{0}\'>resources/glsl/{0}</file>\n'.format(os.path.basename(f))
+ xml += ' <file alias=\'gl/{0}\'>gl/resources/{0}</file>\n'.format(os.path.basename(f))
xml += '\n'
xml += '\n'
for f in vulkan_compiled_shaders:
- xml += ' <file alias=\'vulkan/{0}\'>resources/vulkan/{0}</file>\n'.format(os.path.basename(f))
+ xml += ' <file alias=\'vulkan/{0}\'>vulkan/resources/{0}</file>\n'.format(os.path.basename(f))
xml += '\n'
for f in vulkan_shaders:
- xml += ' <file alias=\'vulkan/{0}\'>resources/vulkan/{0}</file>\n'.format(os.path.basename(f))
+ xml += ' <file alias=\'vulkan/{0}\'>vulkan/resources/{0}</file>\n'.format(os.path.basename(f))
xml += '''
</gresource>
--- /dev/null
+// VERTEX_SHADER:
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+uniform int u_mode;
+uniform sampler2D u_source2;
+
+float
+combine (float source, float backdrop)
+{
+ return source + backdrop * (1.0 - source);
+}
+
+vec4
+composite (vec4 Cs, vec4 Cb, vec3 B)
+{
+ float ao = Cs.a + Cb.a * (1.0 - Cs.a);
+ vec3 Co = (Cs.a*(1.0 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1.0 - Cs.a)*Cb.a*Cb.rgb) / ao;
+ return vec4(Co, ao);
+}
+
+vec4
+normal (vec4 Cs, vec4 Cb)
+{
+ return composite (Cs, Cb, Cs.rgb);
+}
+
+vec4
+multiply (vec4 Cs, vec4 Cb)
+{
+ return composite (Cs, Cb, Cs.rgb * Cb.rgb);
+}
+
+vec4
+difference (vec4 Cs, vec4 Cb)
+{
+ return composite (Cs, Cb, abs(Cs.rgb - Cb.rgb));
+}
+
+vec4
+screen (vec4 Cs, vec4 Cb)
+{
+ return composite (Cs, Cb, Cs.rgb + Cb.rgb - Cs.rgb * Cb.rgb);
+}
+
+float
+hard_light (float source, float backdrop)
+{
+ if (source <= 0.5)
+ return 2.0 * backdrop * source;
+ else
+ return 2.0 * (backdrop + source - backdrop * source) - 1.0;
+}
+
+vec4
+hard_light (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (hard_light (Cs.r, Cb.r),
+ hard_light (Cs.g, Cb.g),
+ hard_light (Cs.b, Cb.b));
+ return composite (Cs, Cb, B);
+}
+
+float
+soft_light (float source, float backdrop)
+{
+ float db;
+
+ if (backdrop <= 0.25)
+ db = ((16.0 * backdrop - 12.0) * backdrop + 4.0) * backdrop;
+ else
+ db = sqrt (backdrop);
+
+ if (source <= 0.5)
+ return backdrop - (1.0 - 2.0 * source) * backdrop * (1.0 - backdrop);
+ else
+ return backdrop + (2.0 * source - 1.0) * (db - backdrop);
+}
+
+vec4
+soft_light (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (soft_light (Cs.r, Cb.r),
+ soft_light (Cs.g, Cb.g),
+ soft_light (Cs.b, Cb.b));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+overlay (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (hard_light (Cb.r, Cs.r),
+ hard_light (Cb.g, Cs.g),
+ hard_light (Cb.b, Cs.b));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+darken (vec4 Cs, vec4 Cb)
+{
+ vec3 B = min (Cs.rgb, Cb.rgb);
+ return composite (Cs, Cb, B);
+}
+
+vec4
+lighten (vec4 Cs, vec4 Cb)
+{
+ vec3 B = max (Cs.rgb, Cb.rgb);
+ return composite (Cs, Cb, B);
+}
+
+float
+color_dodge (float source, float backdrop)
+{
+ return (source == 1.0) ? source : min (backdrop / (1.0 - source), 1.0);
+}
+
+vec4
+color_dodge (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (color_dodge (Cs.r, Cb.r),
+ color_dodge (Cs.g, Cb.g),
+ color_dodge (Cs.b, Cb.b));
+ return composite (Cs, Cb, B);
+}
+
+
+float
+color_burn (float source, float backdrop)
+{
+ return (source == 0.0) ? source : max ((1.0 - ((1.0 - backdrop) / source)), 0.0);
+}
+
+vec4
+color_burn (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (color_burn (Cs.r, Cb.r),
+ color_burn (Cs.g, Cb.g),
+ color_burn (Cs.b, Cb.b));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+exclusion (vec4 Cs, vec4 Cb)
+{
+ vec3 B = Cb.rgb + Cs.rgb - 2.0 * Cb.rgb * Cs.rgb;
+ return composite (Cs, Cb, B);
+}
+
+float
+lum (vec3 c)
+{
+ return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
+}
+
+vec3
+clip_color (vec3 c)
+{
+ float l = lum (c);
+ float n = min (c.r, min (c.g, c.b));
+ float x = max (c.r, max (c.g, c.b));
+ if (n < 0.0) c = l + (((c - l) * l) / (l - n));
+ if (x > 1.0) c = l + (((c - l) * (1.0 - l)) / (x - l));
+ return c;
+}
+
+vec3
+set_lum (vec3 c, float l)
+{
+ float d = l - lum (c);
+ return clip_color (vec3 (c.r + d, c.g + d, c.b + d));
+}
+
+float
+sat (vec3 c)
+{
+ return max (c.r, max (c.g, c.b)) - min (c.r, min (c.g, c.b));
+}
+
+vec3
+set_sat (vec3 c, float s)
+{
+ float cmin = min (c.r, min (c.g, c.b));
+ float cmax = max (c.r, max (c.g, c.b));
+ vec3 res;
+
+ if (cmax == cmin)
+ res = vec3 (0, 0, 0);
+ else
+ {
+ if (c.r == cmax)
+ {
+ if (c.g == cmin)
+ {
+ res.b = ((c.b - cmin) * s) / (cmax - cmin);
+ res.g = 0.0;
+ }
+ else
+ {
+ res.g = ((c.g - cmin) * s) / (cmax - cmin);
+ res.b = 0.0;
+ }
+ res.r = s;
+ }
+ else if (c.g == cmax)
+ {
+ if (c.r == cmin)
+ {
+ res.b = ((c.b - cmin) * s) / (cmax - cmin);
+ res.r = 0.0;
+ }
+ else
+ {
+ res.r = ((c.r - cmin) * s) / (cmax - cmin);
+ res.b = 0.0;
+ }
+ res.g = s;
+ }
+ else
+ {
+ if (c.r == cmin)
+ {
+ res.g = ((c.g - cmin) * s) / (cmax - cmin);
+ res.r = 0.0;
+ }
+ else
+ {
+ res.r = ((c.r - cmin) * s) / (cmax - cmin);
+ res.g = 0.0;
+ }
+ res.b = s;
+ }
+ }
+ return res;
+}
+
+vec4
+color (vec4 Cs, vec4 Cb)
+{
+ vec3 B = set_lum (Cs.rgb, lum (Cb.rgb));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+hue (vec4 Cs, vec4 Cb)
+{
+ vec3 B = set_lum (set_sat (Cs.rgb, sat (Cb.rgb)), lum (Cb.rgb));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+saturation (vec4 Cs, vec4 Cb)
+{
+ vec3 B = set_lum (set_sat (Cb.rgb, sat (Cs.rgb)), lum (Cb.rgb));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+luminosity (vec4 Cs, vec4 Cb)
+{
+ vec3 B = set_lum (Cb.rgb, lum (Cs.rgb));
+ return composite (Cs, Cb, B);
+}
+
+void main() {
+ vec4 bottom_color = GskTexture(u_source, vUv);
+ vec4 top_color = GskTexture(u_source2, vUv);
+
+ vec4 result;
+ if (u_mode == 0)
+ result = normal(top_color, bottom_color);
+ else if (u_mode == 1)
+ result = multiply(top_color, bottom_color);
+ else if (u_mode == 2)
+ result = screen(top_color, bottom_color);
+ else if (u_mode == 3)
+ result = overlay(top_color, bottom_color);
+ else if (u_mode == 4)
+ result = darken(top_color, bottom_color);
+ else if (u_mode == 5)
+ result = lighten(top_color, bottom_color);
+ else if (u_mode == 6)
+ result = color_dodge(top_color, bottom_color);
+ else if (u_mode == 7)
+ result = color_burn(top_color, bottom_color);
+ else if (u_mode == 8)
+ result = hard_light(top_color, bottom_color);
+ else if (u_mode == 9)
+ result = soft_light(top_color, bottom_color);
+ else if (u_mode == 10)
+ result = difference(top_color, bottom_color);
+ else if (u_mode == 11)
+ result = exclusion(top_color, bottom_color);
+ else if (u_mode == 12)
+ result = color(top_color, bottom_color);
+ else if (u_mode == 13)
+ result = hue(top_color, bottom_color);
+ else if (u_mode == 14)
+ result = saturation(top_color, bottom_color);
+ else if (u_mode == 15)
+ result = luminosity(top_color, bottom_color);
+ else
+ discard;
+
+ gskSetOutputColor(result * u_alpha);
+}
--- /dev/null
+// VERTEX_SHADER:
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+void main() {
+ vec4 diffuse = GskTexture(u_source, vUv);
+
+ gskSetOutputColor(diffuse * u_alpha);
+}
--- /dev/null
+// VERTEX_SHADER:
+uniform float u_blur_radius;
+uniform vec2 u_blur_size;
+uniform vec2 u_blur_dir;
+
+_OUT_ vec2 pixel_step;
+_OUT_ float pixels_per_side;
+_OUT_ vec3 initial_gaussian;
+
+const float PI = 3.14159265;
+const float RADIUS_MULTIPLIER = 2.0;
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+
+ pixel_step = (vec2(1.0) / u_blur_size) * u_blur_dir;
+ pixels_per_side = floor(u_blur_radius * RADIUS_MULTIPLIER / 2.0);
+
+ float sigma = u_blur_radius / 2.0; // *shrug*
+ initial_gaussian.x = 1.0 / (sqrt(2.0 * PI) * sigma);
+ initial_gaussian.y = exp(-0.5 / (sigma * sigma));
+ initial_gaussian.z = initial_gaussian.y * initial_gaussian.y;
+}
+
+// FRAGMENT_SHADER:
+_IN_ vec2 pixel_step;
+_IN_ float pixels_per_side;
+_IN_ vec3 initial_gaussian;
+
+// blur_radius 0 is NOT supported and MUST be caught before.
+
+// Partially from http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
+void main() {
+ vec3 incrementalGaussian = initial_gaussian;
+
+ float coefficientSum = 0.0;
+ vec4 sum = GskTexture(u_source, vUv) * incrementalGaussian.x;
+ coefficientSum += incrementalGaussian.x;
+ incrementalGaussian.xy *= incrementalGaussian.yz;
+
+ vec2 p = pixel_step;
+ for (int i = 1; i <= int(pixels_per_side); i++) {
+ sum += GskTexture(u_source, vUv - p) * incrementalGaussian.x;
+ sum += GskTexture(u_source, vUv + p) * incrementalGaussian.x;
+
+ coefficientSum += 2.0 * incrementalGaussian.x;
+ incrementalGaussian.xy *= incrementalGaussian.yz;
+
+ p += pixel_step;
+ }
+
+ gskSetOutputColor(sum / coefficientSum);
+}
--- /dev/null
+// VERTEX_SHADER:
+uniform vec4 u_color;
+uniform vec4 u_widths;
+uniform vec4[3] u_outline_rect;
+
+_OUT_ vec4 final_color;
+_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ final_color = gsk_premultiply(u_color) * u_alpha;
+
+ GskRoundedRect outside = gsk_create_rect(u_outline_rect);
+ GskRoundedRect inside = gsk_rounded_rect_shrink (outside, u_widths);
+
+ gsk_rounded_rect_transform(outside, u_modelview);
+ gsk_rounded_rect_transform(inside, u_modelview);
+
+ gsk_rounded_rect_encode(outside, transformed_outside_outline);
+ gsk_rounded_rect_encode(inside, transformed_inside_outline);
+}
+
+// FRAGMENT_SHADER:
+uniform vec4[3] u_outline_rect;
+
+_IN_ vec4 final_color;
+_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
+
+void main() {
+ vec2 frag = gsk_get_frag_coord();
+
+ float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
+ gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
+ 0.0, 1.0);
+
+ gskSetOutputColor(final_color * alpha);
+}
--- /dev/null
+// VERTEX_SHADER:
+uniform vec4 u_color;
+
+_OUT_ vec4 final_color;
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ final_color = gsk_premultiply(u_color) * u_alpha;
+}
+
+// FRAGMENT_SHADER:
+_IN_ vec4 final_color;
+
+void main() {
+ gskSetOutputColor(final_color);
+}
+
--- /dev/null
+// VERTEX_SHADER:
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+uniform mat4 u_color_matrix;
+uniform vec4 u_color_offset;
+
+void main() {
+ vec4 color = GskTexture(u_source, vUv);
+
+ // Un-premultilpy
+ if (color.a != 0.0)
+ color.rgb /= color.a;
+
+ color = u_color_matrix * color + u_color_offset;
+ color = clamp(color, 0.0, 1.0);
+
+ color.rgb *= color.a;
+
+ gskSetOutputColor(color * u_alpha);
+}
--- /dev/null
+// VERTEX_SHADER:
+uniform vec4 u_color;
+
+_OUT_ vec4 final_color;
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+
+ final_color = gsk_premultiply(u_color) * u_alpha;
+}
+
+// FRAGMENT_SHADER:
+
+_IN_ vec4 final_color;
+
+void main() {
+ vec4 diffuse = GskTexture(u_source, vUv);
+
+ gskSetOutputColor(final_color * diffuse.a);
+}
--- /dev/null
+// VERTEX_SHADER
+uniform vec4 u_geometry;
+
+_NOPERSPECTIVE_ _OUT_ vec2 coord;
+
+void main() {
+ gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
+
+ vec2 mv0 = u_modelview[0].xy;
+ vec2 mv1 = u_modelview[1].xy;
+ vec2 offset = aPosition - u_geometry.xy;
+
+ coord = vec2(dot(mv0, offset),
+ dot(mv1, offset));
+}
+
+// FRAGMENT_SHADER:
+#ifdef GSK_LEGACY
+uniform int u_num_color_stops;
+#else
+uniform highp int u_num_color_stops; // Why? Because it works like this.
+#endif
+
+uniform vec4 u_geometry;
+uniform float u_color_stops[6 * 5];
+
+_NOPERSPECTIVE_ _IN_ vec2 coord;
+
+float get_offset(int index) {
+ return u_color_stops[5 * index];
+}
+
+vec4 get_color(int index) {
+ int base = 5 * index + 1;
+
+ return vec4(u_color_stops[base],
+ u_color_stops[base + 1],
+ u_color_stops[base + 2],
+ u_color_stops[base + 3]);
+}
+
+void main() {
+ // direction of point in range [-PI, PI]
+ vec2 pos = floor(coord);
+ float angle = atan(pos.y, pos.x);
+
+ // fract() does the modulo here, so now we have progress
+ // into the current conic
+ float offset = fract(angle * u_geometry.z + u_geometry.w);
+
+ if (offset < get_offset(0)) {
+ gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
+ return;
+ }
+
+ int n = u_num_color_stops - 1;
+ for (int i = 0; i < n; i++) {
+ float curr_offset = get_offset(i);
+ float next_offset = get_offset(i + 1);
+
+ if (offset >= curr_offset && offset < next_offset) {
+ float f = (offset - curr_offset) / (next_offset - curr_offset);
+ vec4 curr_color = gsk_premultiply(get_color(i));
+ vec4 next_color = gsk_premultiply(get_color(i + 1));
+ vec4 color = mix(curr_color, next_color, f);
+
+ gskSetOutputColor(color * u_alpha);
+ return;
+ }
+ }
+
+ gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
+}
--- /dev/null
+// VERTEX_SHADER:
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+uniform float u_progress;
+uniform sampler2D u_source2;
+
+void main() {
+ vec4 source1 = GskTexture(u_source, vUv); // start child
+ vec4 source2 = GskTexture(u_source2, vUv); // end child
+
+ float p_start = (1.0 - u_progress) * u_alpha;
+ float p_end = u_progress * u_alpha;
+ vec4 color = (p_start * source1) + (p_end * source2);
+ gskSetOutputColor(color);
+}
--- /dev/null
+// VERTEX_SHADER:
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+// The shader supplies:
+void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv);
+
+uniform vec2 u_size;
+uniform sampler2D u_source2;
+uniform sampler2D u_source3;
+uniform sampler2D u_source4;
+
+void main() {
+ vec4 fragColor;
+ vec2 fragCoord = vec2(vUv.x * u_size.x, (1.0-vUv.y) * u_size.y);
+ mainImage(fragColor, fragCoord, u_size, vUv);
+ gskSetOutputColor(fragColor);
+}
--- /dev/null
+// VERTEX_SHADER:
+uniform vec4 u_color;
+uniform float u_spread;
+uniform vec2 u_offset;
+uniform vec4[3] u_outline_rect;
+
+_OUT_ vec4 final_color;
+_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ final_color = gsk_premultiply(u_color) * u_alpha;
+
+ GskRoundedRect outside = gsk_create_rect(u_outline_rect);
+ GskRoundedRect inside = gsk_rounded_rect_shrink(outside, vec4(u_spread));
+
+ gsk_rounded_rect_offset(inside, u_offset);
+
+ gsk_rounded_rect_transform(outside, u_modelview);
+ gsk_rounded_rect_transform(inside, u_modelview);
+
+ gsk_rounded_rect_encode(outside, transformed_outside_outline);
+ gsk_rounded_rect_encode(inside, transformed_inside_outline);
+}
+
+// FRAGMENT_SHADER:
+_IN_ vec4 final_color;
+_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
+
+void main() {
+ vec2 frag = gsk_get_frag_coord();
+
+ float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
+ gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
+ 0.0, 1.0);
+
+ gskSetOutputColor(final_color * alpha);
+}
--- /dev/null
+// VERTEX_SHADER
+uniform vec4 u_points;
+
+_NOPERSPECTIVE_ _OUT_ vec4 info;
+
+void main() {
+ gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
+
+ vec2 mv0 = u_modelview[0].xy;
+ vec2 mv1 = u_modelview[1].xy;
+ vec2 offset = aPosition - u_points.xy;
+ vec2 coord = vec2(dot(mv0, offset),
+ dot(mv1, offset));
+
+ // Original equation:
+ // VS | maxDist = length(end - start);
+ // VS | gradient = end - start;
+ // VS | gradientLength = length(gradient);
+ // FS | pos = frag_coord - start
+ // FS | proj = (dot(gradient, pos) / (gradientLength * gradientLength)) * gradient
+ // FS | offset = length(proj) / maxDist
+
+ // Simplified formula derivation:
+ // 1. Notice that maxDist = gradientLength:
+ // offset = length(proj) / gradientLength
+ // 2. Let gnorm = gradient / gradientLength, then:
+ // proj = (dot(gnorm * gradientLength, pos) / (gradientLength * gradientLength)) * (gnorm * gradientLength) =
+ // = dot(gnorm, pos) * gnorm
+ // 3. Since gnorm is unit length then:
+ // length(proj) = length(dot(gnorm, pos) * gnorm) = dot(gnorm, pos)
+ // 4. We can avoid the FS division by passing a scaled pos from the VS:
+ // offset = dot(gnorm, pos) / gradientLength = dot(gnorm, pos / gradientLength)
+ // 5. 1.0 / length(gradient) is inversesqrt(dot(gradient, gradient)) in GLSL
+ vec2 gradient = vec2(dot(mv0, u_points.zw),
+ dot(mv1, u_points.zw));
+ float rcp_gradient_length = inversesqrt(dot(gradient, gradient));
+
+ info = rcp_gradient_length * vec4(coord, gradient);
+}
+
+// FRAGMENT_SHADER:
+#ifdef GSK_LEGACY
+uniform int u_num_color_stops;
+#else
+uniform highp int u_num_color_stops; // Why? Because it works like this.
+#endif
+
+uniform float u_color_stops[6 * 5];
+uniform bool u_repeat;
+
+_NOPERSPECTIVE_ _IN_ vec4 info;
+
+float get_offset(int index) {
+ return u_color_stops[5 * index];
+}
+
+vec4 get_color(int index) {
+ int base = 5 * index + 1;
+
+ return vec4(u_color_stops[base],
+ u_color_stops[base + 1],
+ u_color_stops[base + 2],
+ u_color_stops[base + 3]);
+}
+
+void main() {
+ float offset = dot(info.xy, info.zw);
+
+ if (u_repeat) {
+ offset = fract(offset);
+ }
+
+ if (offset < get_offset(0)) {
+ gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
+ return;
+ }
+
+ int n = u_num_color_stops - 1;
+ for (int i = 0; i < n; i++) {
+ float curr_offset = get_offset(i);
+ float next_offset = get_offset(i + 1);
+
+ if (offset >= curr_offset && offset < next_offset) {
+ float f = (offset - curr_offset) / (next_offset - curr_offset);
+ vec4 curr_color = gsk_premultiply(get_color(i));
+ vec4 next_color = gsk_premultiply(get_color(i + 1));
+ vec4 color = mix(curr_color, next_color, f);
+
+ gskSetOutputColor(color * u_alpha);
+ return;
+ }
+ }
+
+ gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
+}
--- /dev/null
+// VERTEX_SHADER:
+uniform vec4 u_color;
+uniform vec4[3] u_outline_rect;
+
+_OUT_ vec4 final_color;
+_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outline;
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+
+ final_color = gsk_premultiply(u_color) * u_alpha;
+
+ GskRoundedRect outline = gsk_create_rect(u_outline_rect);
+ gsk_rounded_rect_transform(outline, u_modelview);
+ gsk_rounded_rect_encode(outline, transformed_outline);
+}
+
+// FRAGMENT_SHADER:
+_IN_ vec4 final_color;
+_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outline;
+
+void main() {
+ vec2 frag = gsk_get_frag_coord();
+
+ float alpha = GskTexture(u_source, vUv).a;
+ alpha *= (1.0 - clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outline), frag), 0.0, 1.0));
+
+ vec4 color = final_color * alpha;
+
+ gskSetOutputColor(color);
+}
--- /dev/null
+uniform sampler2D u_source;
+uniform mat4 u_projection;
+uniform mat4 u_modelview;
+uniform float u_alpha;// = 1.0;
+uniform vec4 u_viewport;
+uniform vec4[3] u_clip_rect;
+
+#if defined(GSK_LEGACY)
+_OUT_ vec4 outputColor;
+#elif !defined(GSK_GLES)
+_OUT_ vec4 outputColor;
+#endif
+
+_IN_ vec2 vUv;
+
+
+
+GskRoundedRect gsk_decode_rect(_GSK_ROUNDED_RECT_UNIFORM_ r)
+{
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+ return GskRoundedRect(r[0], r[1], r[2]);
+#else
+ return r;
+#endif
+}
+
+float
+gsk_ellipsis_dist (vec2 p, vec2 radius)
+{
+ if (radius == vec2(0, 0))
+ return 0.0;
+
+ vec2 p0 = p / radius;
+ vec2 p1 = 2.0 * p0 / radius;
+
+ return (dot(p0, p0) - 1.0) / length (p1);
+}
+
+float
+gsk_ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
+{
+ float d = gsk_ellipsis_dist (point - center, radius);
+ return clamp (0.5 - d, 0.0, 1.0);
+}
+
+float
+gsk_rounded_rect_coverage (GskRoundedRect r, vec2 p)
+{
+ if (p.x < r.bounds.x || p.y < r.bounds.y ||
+ p.x >= r.bounds.z || p.y >= r.bounds.w)
+ return 0.0;
+
+ vec2 ref_tl = r.corner_points1.xy;
+ vec2 ref_tr = r.corner_points1.zw;
+ vec2 ref_br = r.corner_points2.xy;
+ vec2 ref_bl = r.corner_points2.zw;
+
+ if (p.x >= ref_tl.x && p.x >= ref_bl.x &&
+ p.x <= ref_tr.x && p.x <= ref_br.x)
+ return 1.0;
+
+ if (p.y >= ref_tl.y && p.y >= ref_tr.y &&
+ p.y <= ref_bl.y && p.y <= ref_br.y)
+ return 1.0;
+
+ vec2 rad_tl = r.corner_points1.xy - r.bounds.xy;
+ vec2 rad_tr = r.corner_points1.zw - r.bounds.zy;
+ vec2 rad_br = r.corner_points2.xy - r.bounds.zw;
+ vec2 rad_bl = r.corner_points2.zw - r.bounds.xw;
+
+ float d_tl = gsk_ellipsis_coverage(p, ref_tl, rad_tl);
+ float d_tr = gsk_ellipsis_coverage(p, ref_tr, rad_tr);
+ float d_br = gsk_ellipsis_coverage(p, ref_br, rad_br);
+ float d_bl = gsk_ellipsis_coverage(p, ref_bl, rad_bl);
+
+ vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
+
+ bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
+ p.x > ref_tr.x && p.y < ref_tr.y,
+ p.x > ref_br.x && p.y > ref_br.y,
+ p.x < ref_bl.x && p.y > ref_bl.y);
+
+ return 1.0 - dot(vec4(is_out), corner_coverages);
+}
+
+float
+gsk_rect_coverage (vec4 r, vec2 p)
+{
+ if (p.x < r.x || p.y < r.y ||
+ p.x >= r.z || p.y >= r.w)
+ return 0.0;
+
+ return 1.0;
+}
+
+vec4 GskTexture(sampler2D sampler, vec2 texCoords) {
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+ return texture2D(sampler, texCoords);
+#else
+ return texture(sampler, texCoords);
+#endif
+}
+
+#ifdef GSK_GL3
+layout(origin_upper_left) in vec4 gl_FragCoord;
+#endif
+
+vec2 gsk_get_frag_coord() {
+ vec2 fc = gl_FragCoord.xy;
+
+#ifdef GSK_GL3
+ fc += u_viewport.xy;
+#else
+ fc.x += u_viewport.x;
+ fc.y = (u_viewport.y + u_viewport.w) - fc.y;
+#endif
+
+ return fc;
+}
+
+void gskSetOutputColor(vec4 color) {
+ vec4 result;
+
+#if defined(NO_CLIP)
+ result = color;
+#elif defined(RECT_CLIP)
+ result = color * gsk_rect_coverage(gsk_get_bounds(u_clip_rect),
+ gsk_get_frag_coord());
+#else
+ result = color * gsk_rounded_rect_coverage(gsk_create_rect(u_clip_rect),
+ gsk_get_frag_coord());
+#endif
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+ gl_FragColor = result;
+#else
+ outputColor = result;
+#endif
+}
--- /dev/null
+#ifndef GSK_LEGACY
+precision highp float;
+#endif
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+#define _OUT_ varying
+#define _IN_ varying
+#define _NOPERSPECTIVE_
+#define _GSK_ROUNDED_RECT_UNIFORM_ vec4[3]
+#else
+#define _OUT_ out
+#define _IN_ in
+#define _NOPERSPECTIVE_ noperspective
+#define _GSK_ROUNDED_RECT_UNIFORM_ GskRoundedRect
+#endif
+
+
+struct GskRoundedRect
+{
+ vec4 bounds; // Top left and bottom right
+ // Look, arrays can't be in structs if you want to return the struct
+ // from a function in gles or whatever. Just kill me.
+ vec4 corner_points1; // xy = top left, zw = top right
+ vec4 corner_points2; // xy = bottom right, zw = bottom left
+};
+
+// Transform from a C GskRoundedRect to what we need.
+GskRoundedRect
+gsk_create_rect(vec4[3] data)
+{
+ vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
+
+ vec4 corner_points1 = vec4(bounds.xy + data[1].xy,
+ bounds.zy + vec2(data[1].zw * vec2(-1, 1)));
+ vec4 corner_points2 = vec4(bounds.zw + (data[2].xy * vec2(-1, -1)),
+ bounds.xw + vec2(data[2].zw * vec2(1, -1)));
+
+ return GskRoundedRect(bounds, corner_points1, corner_points2);
+}
+
+vec4
+gsk_get_bounds(vec4[3] data)
+{
+ return vec4(data[0].xy, data[0].xy + data[0].zw);
+}
+
+vec4 gsk_premultiply(vec4 c) {
+ return vec4(c.rgb * c.a, c.a);
+}
+
+vec4 gsk_scaled_premultiply(vec4 c, float s) {
+ // Fast version of gsk_premultiply(c) * s
+ // 4 muls instead of 7
+ float a = s * c.a;
+
+ return vec4(c.rgb * a, a);
+}
--- /dev/null
+uniform mat4 u_projection;
+uniform mat4 u_modelview;
+uniform float u_alpha;
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+attribute vec2 aPosition;
+attribute vec2 aUv;
+_OUT_ vec2 vUv;
+#else
+_IN_ vec2 aPosition;
+_IN_ vec2 aUv;
+_OUT_ vec2 vUv;
+#endif
+
+// amount is: top, right, bottom, left
+GskRoundedRect
+gsk_rounded_rect_shrink (GskRoundedRect r, vec4 amount)
+{
+ vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
+ vec4 new_corner_points1 = r.corner_points1;
+ vec4 new_corner_points2 = r.corner_points2;
+
+ if (r.corner_points1.xy == r.bounds.xy) new_corner_points1.xy = new_bounds.xy;
+ if (r.corner_points1.zw == r.bounds.zy) new_corner_points1.zw = new_bounds.zy;
+ if (r.corner_points2.xy == r.bounds.zw) new_corner_points2.xy = new_bounds.zw;
+ if (r.corner_points2.zw == r.bounds.xw) new_corner_points2.zw = new_bounds.xw;
+
+ return GskRoundedRect (new_bounds, new_corner_points1, new_corner_points2);
+}
+
+void
+gsk_rounded_rect_offset(inout GskRoundedRect r, vec2 offset)
+{
+ r.bounds.xy += offset;
+ r.bounds.zw += offset;
+ r.corner_points1.xy += offset;
+ r.corner_points1.zw += offset;
+ r.corner_points2.xy += offset;
+ r.corner_points2.zw += offset;
+}
+
+void gsk_rounded_rect_transform(inout GskRoundedRect r, mat4 mat)
+{
+ r.bounds.xy = (mat * vec4(r.bounds.xy, 0.0, 1.0)).xy;
+ r.bounds.zw = (mat * vec4(r.bounds.zw, 0.0, 1.0)).xy;
+
+ r.corner_points1.xy = (mat * vec4(r.corner_points1.xy, 0.0, 1.0)).xy;
+ r.corner_points1.zw = (mat * vec4(r.corner_points1.zw, 0.0, 1.0)).xy;
+
+ r.corner_points2.xy = (mat * vec4(r.corner_points2.xy, 0.0, 1.0)).xy;
+ r.corner_points2.zw = (mat * vec4(r.corner_points2.zw, 0.0, 1.0)).xy;
+}
+
+#if defined(GSK_LEGACY)
+// Can't have out or inout array parameters...
+#define gsk_rounded_rect_encode(r, uni) uni[0] = r.bounds; uni[1] = r.corner_points1; uni[2] = r.corner_points2;
+#else
+void gsk_rounded_rect_encode(GskRoundedRect r, out _GSK_ROUNDED_RECT_UNIFORM_ out_r)
+{
+#if defined(GSK_GLES)
+ out_r[0] = r.bounds;
+ out_r[1] = r.corner_points1;
+ out_r[2] = r.corner_points2;
+#else
+ out_r = r;
+#endif
+}
+
+#endif
--- /dev/null
+// VERTEX_SHADER
+uniform vec4 u_geometry;
+
+_NOPERSPECTIVE_ _OUT_ vec2 coord;
+
+void main() {
+ gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
+
+ vec2 mv0 = u_modelview[0].xy;
+ vec2 mv1 = u_modelview[1].xy;
+ vec2 offset = aPosition - u_geometry.xy;
+ vec2 dir = vec2(dot(mv0, offset),
+ dot(mv1, offset));
+
+ coord = dir * u_geometry.zw;
+}
+
+// FRAGMENT_SHADER:
+#ifdef GSK_LEGACY
+uniform int u_num_color_stops;
+#else
+uniform highp int u_num_color_stops;
+#endif
+
+uniform bool u_repeat;
+uniform vec2 u_range;
+uniform float u_color_stops[6 * 5];
+
+_NOPERSPECTIVE_ _IN_ vec2 coord;
+
+float get_offset(int index) {
+ return u_color_stops[5 * index];
+}
+
+vec4 get_color(int index) {
+ int base = 5 * index + 1;
+
+ return vec4(u_color_stops[base],
+ u_color_stops[base + 1],
+ u_color_stops[base + 2],
+ u_color_stops[base + 3]);
+}
+
+void main() {
+ // Reverse scale
+ float offset = length(coord) * u_range.x + u_range.y;
+
+ if (u_repeat) {
+ offset = fract(offset);
+ }
+
+ if (offset < get_offset(0)) {
+ gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
+ return;
+ }
+
+ int n = u_num_color_stops - 1;
+ for (int i = 0; i < n; i++) {
+ float curr_offset = get_offset(i);
+ float next_offset = get_offset(i + 1);
+
+ if (offset >= curr_offset && offset < next_offset) {
+ float f = (offset - curr_offset) / (next_offset - curr_offset);
+ vec4 curr_color = gsk_premultiply(get_color(i));
+ vec4 next_color = gsk_premultiply(get_color(i + 1));
+ vec4 color = mix(curr_color, next_color, f);
+
+ gskSetOutputColor(color * u_alpha);
+ return;
+ }
+ }
+
+ gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
+}
--- /dev/null
+// VERTEX_SHADER:
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+uniform vec4 u_child_bounds;
+uniform vec4 u_texture_rect;
+
+
+float wrap(float f, float wrap_for) {
+ return mod(f, wrap_for);
+}
+
+/* We get the texture coordinates via vUv,
+ * but that might be on a texture atlas, so we need to do the
+ * wrapping ourselves.
+ */
+void main() {
+
+ /* We map the texture coordinate to [1;0], then wrap it and scale the result again */
+
+ float tw = u_texture_rect.z - u_texture_rect.x;
+ float th = u_texture_rect.w - u_texture_rect.y;
+
+ float mapped_x = (vUv.x - u_texture_rect.x) / tw;
+ float mapped_y = (vUv.y - u_texture_rect.y) / th;
+
+ float wrapped_x = wrap(u_child_bounds.x + mapped_x * u_child_bounds.z, 1.0);
+ float wrapped_y = wrap(u_child_bounds.y + mapped_y * u_child_bounds.w, 1.0);
+
+ vec2 tp;
+ tp.x = u_texture_rect.x + (wrapped_x * tw);
+ tp.y = u_texture_rect.y + (wrapped_y * th);
+
+ vec4 diffuse = GskTexture(u_source, tp);
+
+ gskSetOutputColor(diffuse * u_alpha);
+}
--- /dev/null
+// VERTEX_SHADER:
+uniform vec4 u_color;
+uniform float u_spread;
+uniform vec2 u_offset;
+uniform vec4[3] u_outline_rect;
+
+_OUT_ vec4 final_color;
+_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ final_color = gsk_premultiply(u_color) * u_alpha;
+
+ GskRoundedRect inside = gsk_create_rect(u_outline_rect);
+ GskRoundedRect outside = gsk_rounded_rect_shrink(inside, vec4(- u_spread));
+
+ gsk_rounded_rect_offset(outside, u_offset);
+
+ gsk_rounded_rect_transform(outside, u_modelview);
+ gsk_rounded_rect_transform(inside, u_modelview);
+
+ gsk_rounded_rect_encode(outside, transformed_outside_outline);
+ gsk_rounded_rect_encode(inside, transformed_inside_outline);
+}
+
+// FRAGMENT_SHADER:
+_IN_ vec4 final_color;
+_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
+
+void main() {
+ vec2 frag = gsk_get_frag_coord();
+
+ float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
+ gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
+ 0.0, 1.0);
+
+ gskSetOutputColor(final_color * alpha);
+}
+
gsk_private_gl_shaders = [
- 'resources/glsl/preamble.glsl',
- 'resources/glsl/preamble.fs.glsl',
- 'resources/glsl/preamble.vs.glsl',
- 'resources/glsl/border.glsl',
- 'resources/glsl/blit.glsl',
- 'resources/glsl/coloring.glsl',
- 'resources/glsl/color.glsl',
- 'resources/glsl/linear_gradient.glsl',
- 'resources/glsl/radial_gradient.glsl',
- 'resources/glsl/conic_gradient.glsl',
- 'resources/glsl/color_matrix.glsl',
- 'resources/glsl/blur.glsl',
- 'resources/glsl/inset_shadow.glsl',
- 'resources/glsl/outset_shadow.glsl',
- 'resources/glsl/unblurred_outset_shadow.glsl',
- 'resources/glsl/cross_fade.glsl',
- 'resources/glsl/blend.glsl',
- 'resources/glsl/repeat.glsl',
- 'resources/glsl/custom.glsl',
+ 'gl/resources/preamble.glsl',
+ 'gl/resources/preamble.fs.glsl',
+ 'gl/resources/preamble.vs.glsl',
+ 'gl/resources/border.glsl',
+ 'gl/resources/blit.glsl',
+ 'gl/resources/coloring.glsl',
+ 'gl/resources/color.glsl',
+ 'gl/resources/linear_gradient.glsl',
+ 'gl/resources/radial_gradient.glsl',
+ 'gl/resources/conic_gradient.glsl',
+ 'gl/resources/color_matrix.glsl',
+ 'gl/resources/blur.glsl',
+ 'gl/resources/inset_shadow.glsl',
+ 'gl/resources/outset_shadow.glsl',
+ 'gl/resources/unblurred_outset_shadow.glsl',
+ 'gl/resources/cross_fade.glsl',
+ 'gl/resources/blend.glsl',
+ 'gl/resources/repeat.glsl',
+ 'gl/resources/custom.glsl',
]
gsk_private_ngl_shaders = [
'vulkan/gskvulkanshader.c',
])
- subdir('resources/vulkan')
+ subdir('vulkan/resources')
endif # have_vulkan
if get_variable('broadway_enabled')
+++ /dev/null
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-uniform int u_mode;
-uniform sampler2D u_source2;
-
-float
-combine (float source, float backdrop)
-{
- return source + backdrop * (1.0 - source);
-}
-
-vec4
-composite (vec4 Cs, vec4 Cb, vec3 B)
-{
- float ao = Cs.a + Cb.a * (1.0 - Cs.a);
- vec3 Co = (Cs.a*(1.0 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1.0 - Cs.a)*Cb.a*Cb.rgb) / ao;
- return vec4(Co, ao);
-}
-
-vec4
-normal (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb);
-}
-
-vec4
-multiply (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb * Cb.rgb);
-}
-
-vec4
-difference (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, abs(Cs.rgb - Cb.rgb));
-}
-
-vec4
-screen (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb + Cb.rgb - Cs.rgb * Cb.rgb);
-}
-
-float
-hard_light (float source, float backdrop)
-{
- if (source <= 0.5)
- return 2.0 * backdrop * source;
- else
- return 2.0 * (backdrop + source - backdrop * source) - 1.0;
-}
-
-vec4
-hard_light (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (hard_light (Cs.r, Cb.r),
- hard_light (Cs.g, Cb.g),
- hard_light (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-float
-soft_light (float source, float backdrop)
-{
- float db;
-
- if (backdrop <= 0.25)
- db = ((16.0 * backdrop - 12.0) * backdrop + 4.0) * backdrop;
- else
- db = sqrt (backdrop);
-
- if (source <= 0.5)
- return backdrop - (1.0 - 2.0 * source) * backdrop * (1.0 - backdrop);
- else
- return backdrop + (2.0 * source - 1.0) * (db - backdrop);
-}
-
-vec4
-soft_light (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (soft_light (Cs.r, Cb.r),
- soft_light (Cs.g, Cb.g),
- soft_light (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-overlay (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (hard_light (Cb.r, Cs.r),
- hard_light (Cb.g, Cs.g),
- hard_light (Cb.b, Cs.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-darken (vec4 Cs, vec4 Cb)
-{
- vec3 B = min (Cs.rgb, Cb.rgb);
- return composite (Cs, Cb, B);
-}
-
-vec4
-lighten (vec4 Cs, vec4 Cb)
-{
- vec3 B = max (Cs.rgb, Cb.rgb);
- return composite (Cs, Cb, B);
-}
-
-float
-color_dodge (float source, float backdrop)
-{
- return (source == 1.0) ? source : min (backdrop / (1.0 - source), 1.0);
-}
-
-vec4
-color_dodge (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (color_dodge (Cs.r, Cb.r),
- color_dodge (Cs.g, Cb.g),
- color_dodge (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-
-float
-color_burn (float source, float backdrop)
-{
- return (source == 0.0) ? source : max ((1.0 - ((1.0 - backdrop) / source)), 0.0);
-}
-
-vec4
-color_burn (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (color_burn (Cs.r, Cb.r),
- color_burn (Cs.g, Cb.g),
- color_burn (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-exclusion (vec4 Cs, vec4 Cb)
-{
- vec3 B = Cb.rgb + Cs.rgb - 2.0 * Cb.rgb * Cs.rgb;
- return composite (Cs, Cb, B);
-}
-
-float
-lum (vec3 c)
-{
- return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
-}
-
-vec3
-clip_color (vec3 c)
-{
- float l = lum (c);
- float n = min (c.r, min (c.g, c.b));
- float x = max (c.r, max (c.g, c.b));
- if (n < 0.0) c = l + (((c - l) * l) / (l - n));
- if (x > 1.0) c = l + (((c - l) * (1.0 - l)) / (x - l));
- return c;
-}
-
-vec3
-set_lum (vec3 c, float l)
-{
- float d = l - lum (c);
- return clip_color (vec3 (c.r + d, c.g + d, c.b + d));
-}
-
-float
-sat (vec3 c)
-{
- return max (c.r, max (c.g, c.b)) - min (c.r, min (c.g, c.b));
-}
-
-vec3
-set_sat (vec3 c, float s)
-{
- float cmin = min (c.r, min (c.g, c.b));
- float cmax = max (c.r, max (c.g, c.b));
- vec3 res;
-
- if (cmax == cmin)
- res = vec3 (0, 0, 0);
- else
- {
- if (c.r == cmax)
- {
- if (c.g == cmin)
- {
- res.b = ((c.b - cmin) * s) / (cmax - cmin);
- res.g = 0.0;
- }
- else
- {
- res.g = ((c.g - cmin) * s) / (cmax - cmin);
- res.b = 0.0;
- }
- res.r = s;
- }
- else if (c.g == cmax)
- {
- if (c.r == cmin)
- {
- res.b = ((c.b - cmin) * s) / (cmax - cmin);
- res.r = 0.0;
- }
- else
- {
- res.r = ((c.r - cmin) * s) / (cmax - cmin);
- res.b = 0.0;
- }
- res.g = s;
- }
- else
- {
- if (c.r == cmin)
- {
- res.g = ((c.g - cmin) * s) / (cmax - cmin);
- res.r = 0.0;
- }
- else
- {
- res.r = ((c.r - cmin) * s) / (cmax - cmin);
- res.g = 0.0;
- }
- res.b = s;
- }
- }
- return res;
-}
-
-vec4
-color (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (Cs.rgb, lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-hue (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (set_sat (Cs.rgb, sat (Cb.rgb)), lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-saturation (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (set_sat (Cb.rgb, sat (Cs.rgb)), lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-luminosity (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (Cb.rgb, lum (Cs.rgb));
- return composite (Cs, Cb, B);
-}
-
-void main() {
- vec4 bottom_color = GskTexture(u_source, vUv);
- vec4 top_color = GskTexture(u_source2, vUv);
-
- vec4 result;
- if (u_mode == 0)
- result = normal(top_color, bottom_color);
- else if (u_mode == 1)
- result = multiply(top_color, bottom_color);
- else if (u_mode == 2)
- result = screen(top_color, bottom_color);
- else if (u_mode == 3)
- result = overlay(top_color, bottom_color);
- else if (u_mode == 4)
- result = darken(top_color, bottom_color);
- else if (u_mode == 5)
- result = lighten(top_color, bottom_color);
- else if (u_mode == 6)
- result = color_dodge(top_color, bottom_color);
- else if (u_mode == 7)
- result = color_burn(top_color, bottom_color);
- else if (u_mode == 8)
- result = hard_light(top_color, bottom_color);
- else if (u_mode == 9)
- result = soft_light(top_color, bottom_color);
- else if (u_mode == 10)
- result = difference(top_color, bottom_color);
- else if (u_mode == 11)
- result = exclusion(top_color, bottom_color);
- else if (u_mode == 12)
- result = color(top_color, bottom_color);
- else if (u_mode == 13)
- result = hue(top_color, bottom_color);
- else if (u_mode == 14)
- result = saturation(top_color, bottom_color);
- else if (u_mode == 15)
- result = luminosity(top_color, bottom_color);
- else
- discard;
-
- gskSetOutputColor(result * u_alpha);
-}
+++ /dev/null
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-void main() {
- vec4 diffuse = GskTexture(u_source, vUv);
-
- gskSetOutputColor(diffuse * u_alpha);
-}
+++ /dev/null
-// VERTEX_SHADER:
-uniform float u_blur_radius;
-uniform vec2 u_blur_size;
-uniform vec2 u_blur_dir;
-
-_OUT_ vec2 pixel_step;
-_OUT_ float pixels_per_side;
-_OUT_ vec3 initial_gaussian;
-
-const float PI = 3.14159265;
-const float RADIUS_MULTIPLIER = 2.0;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-
- pixel_step = (vec2(1.0) / u_blur_size) * u_blur_dir;
- pixels_per_side = floor(u_blur_radius * RADIUS_MULTIPLIER / 2.0);
-
- float sigma = u_blur_radius / 2.0; // *shrug*
- initial_gaussian.x = 1.0 / (sqrt(2.0 * PI) * sigma);
- initial_gaussian.y = exp(-0.5 / (sigma * sigma));
- initial_gaussian.z = initial_gaussian.y * initial_gaussian.y;
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec2 pixel_step;
-_IN_ float pixels_per_side;
-_IN_ vec3 initial_gaussian;
-
-// blur_radius 0 is NOT supported and MUST be caught before.
-
-// Partially from http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
-void main() {
- vec3 incrementalGaussian = initial_gaussian;
-
- float coefficientSum = 0.0;
- vec4 sum = GskTexture(u_source, vUv) * incrementalGaussian.x;
- coefficientSum += incrementalGaussian.x;
- incrementalGaussian.xy *= incrementalGaussian.yz;
-
- vec2 p = pixel_step;
- for (int i = 1; i <= int(pixels_per_side); i++) {
- sum += GskTexture(u_source, vUv - p) * incrementalGaussian.x;
- sum += GskTexture(u_source, vUv + p) * incrementalGaussian.x;
-
- coefficientSum += 2.0 * incrementalGaussian.x;
- incrementalGaussian.xy *= incrementalGaussian.yz;
-
- p += pixel_step;
- }
-
- gskSetOutputColor(sum / coefficientSum);
-}
+++ /dev/null
-// VERTEX_SHADER:
-uniform vec4 u_color;
-uniform vec4 u_widths;
-uniform vec4[3] u_outline_rect;
-
-_OUT_ vec4 final_color;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-
- GskRoundedRect outside = gsk_create_rect(u_outline_rect);
- GskRoundedRect inside = gsk_rounded_rect_shrink (outside, u_widths);
-
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
-
- gsk_rounded_rect_encode(outside, transformed_outside_outline);
- gsk_rounded_rect_encode(inside, transformed_inside_outline);
-}
-
-// FRAGMENT_SHADER:
-uniform vec4[3] u_outline_rect;
-
-_IN_ vec4 final_color;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- vec2 frag = gsk_get_frag_coord();
-
- float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
- gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
- 0.0, 1.0);
-
- gskSetOutputColor(final_color * alpha);
-}
+++ /dev/null
-// VERTEX_SHADER:
-uniform vec4 u_color;
-
-_OUT_ vec4 final_color;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec4 final_color;
-
-void main() {
- gskSetOutputColor(final_color);
-}
-
+++ /dev/null
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-uniform mat4 u_color_matrix;
-uniform vec4 u_color_offset;
-
-void main() {
- vec4 color = GskTexture(u_source, vUv);
-
- // Un-premultilpy
- if (color.a != 0.0)
- color.rgb /= color.a;
-
- color = u_color_matrix * color + u_color_offset;
- color = clamp(color, 0.0, 1.0);
-
- color.rgb *= color.a;
-
- gskSetOutputColor(color * u_alpha);
-}
+++ /dev/null
-// VERTEX_SHADER:
-uniform vec4 u_color;
-
-_OUT_ vec4 final_color;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-}
-
-// FRAGMENT_SHADER:
-
-_IN_ vec4 final_color;
-
-void main() {
- vec4 diffuse = GskTexture(u_source, vUv);
-
- gskSetOutputColor(final_color * diffuse.a);
-}
+++ /dev/null
-// VERTEX_SHADER
-uniform vec4 u_geometry;
-
-_NOPERSPECTIVE_ _OUT_ vec2 coord;
-
-void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
-
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
- vec2 offset = aPosition - u_geometry.xy;
-
- coord = vec2(dot(mv0, offset),
- dot(mv1, offset));
-}
-
-// FRAGMENT_SHADER:
-#ifdef GSK_LEGACY
-uniform int u_num_color_stops;
-#else
-uniform highp int u_num_color_stops; // Why? Because it works like this.
-#endif
-
-uniform vec4 u_geometry;
-uniform float u_color_stops[6 * 5];
-
-_NOPERSPECTIVE_ _IN_ vec2 coord;
-
-float get_offset(int index) {
- return u_color_stops[5 * index];
-}
-
-vec4 get_color(int index) {
- int base = 5 * index + 1;
-
- return vec4(u_color_stops[base],
- u_color_stops[base + 1],
- u_color_stops[base + 2],
- u_color_stops[base + 3]);
-}
-
-void main() {
- // direction of point in range [-PI, PI]
- vec2 pos = floor(coord);
- float angle = atan(pos.y, pos.x);
-
- // fract() does the modulo here, so now we have progress
- // into the current conic
- float offset = fract(angle * u_geometry.z + u_geometry.w);
-
- if (offset < get_offset(0)) {
- gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
- return;
- }
-
- int n = u_num_color_stops - 1;
- for (int i = 0; i < n; i++) {
- float curr_offset = get_offset(i);
- float next_offset = get_offset(i + 1);
-
- if (offset >= curr_offset && offset < next_offset) {
- float f = (offset - curr_offset) / (next_offset - curr_offset);
- vec4 curr_color = gsk_premultiply(get_color(i));
- vec4 next_color = gsk_premultiply(get_color(i + 1));
- vec4 color = mix(curr_color, next_color, f);
-
- gskSetOutputColor(color * u_alpha);
- return;
- }
- }
-
- gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
-}
+++ /dev/null
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-uniform float u_progress;
-uniform sampler2D u_source2;
-
-void main() {
- vec4 source1 = GskTexture(u_source, vUv); // start child
- vec4 source2 = GskTexture(u_source2, vUv); // end child
-
- float p_start = (1.0 - u_progress) * u_alpha;
- float p_end = u_progress * u_alpha;
- vec4 color = (p_start * source1) + (p_end * source2);
- gskSetOutputColor(color);
-}
+++ /dev/null
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-// The shader supplies:
-void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv);
-
-uniform vec2 u_size;
-uniform sampler2D u_source2;
-uniform sampler2D u_source3;
-uniform sampler2D u_source4;
-
-void main() {
- vec4 fragColor;
- vec2 fragCoord = vec2(vUv.x * u_size.x, (1.0-vUv.y) * u_size.y);
- mainImage(fragColor, fragCoord, u_size, vUv);
- gskSetOutputColor(fragColor);
-}
+++ /dev/null
-// VERTEX_SHADER:
-uniform vec4 u_color;
-uniform float u_spread;
-uniform vec2 u_offset;
-uniform vec4[3] u_outline_rect;
-
-_OUT_ vec4 final_color;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-
- GskRoundedRect outside = gsk_create_rect(u_outline_rect);
- GskRoundedRect inside = gsk_rounded_rect_shrink(outside, vec4(u_spread));
-
- gsk_rounded_rect_offset(inside, u_offset);
-
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
-
- gsk_rounded_rect_encode(outside, transformed_outside_outline);
- gsk_rounded_rect_encode(inside, transformed_inside_outline);
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec4 final_color;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- vec2 frag = gsk_get_frag_coord();
-
- float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
- gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
- 0.0, 1.0);
-
- gskSetOutputColor(final_color * alpha);
-}
+++ /dev/null
-// VERTEX_SHADER
-uniform vec4 u_points;
-
-_NOPERSPECTIVE_ _OUT_ vec4 info;
-
-void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
-
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
- vec2 offset = aPosition - u_points.xy;
- vec2 coord = vec2(dot(mv0, offset),
- dot(mv1, offset));
-
- // Original equation:
- // VS | maxDist = length(end - start);
- // VS | gradient = end - start;
- // VS | gradientLength = length(gradient);
- // FS | pos = frag_coord - start
- // FS | proj = (dot(gradient, pos) / (gradientLength * gradientLength)) * gradient
- // FS | offset = length(proj) / maxDist
-
- // Simplified formula derivation:
- // 1. Notice that maxDist = gradientLength:
- // offset = length(proj) / gradientLength
- // 2. Let gnorm = gradient / gradientLength, then:
- // proj = (dot(gnorm * gradientLength, pos) / (gradientLength * gradientLength)) * (gnorm * gradientLength) =
- // = dot(gnorm, pos) * gnorm
- // 3. Since gnorm is unit length then:
- // length(proj) = length(dot(gnorm, pos) * gnorm) = dot(gnorm, pos)
- // 4. We can avoid the FS division by passing a scaled pos from the VS:
- // offset = dot(gnorm, pos) / gradientLength = dot(gnorm, pos / gradientLength)
- // 5. 1.0 / length(gradient) is inversesqrt(dot(gradient, gradient)) in GLSL
- vec2 gradient = vec2(dot(mv0, u_points.zw),
- dot(mv1, u_points.zw));
- float rcp_gradient_length = inversesqrt(dot(gradient, gradient));
-
- info = rcp_gradient_length * vec4(coord, gradient);
-}
-
-// FRAGMENT_SHADER:
-#ifdef GSK_LEGACY
-uniform int u_num_color_stops;
-#else
-uniform highp int u_num_color_stops; // Why? Because it works like this.
-#endif
-
-uniform float u_color_stops[6 * 5];
-uniform bool u_repeat;
-
-_NOPERSPECTIVE_ _IN_ vec4 info;
-
-float get_offset(int index) {
- return u_color_stops[5 * index];
-}
-
-vec4 get_color(int index) {
- int base = 5 * index + 1;
-
- return vec4(u_color_stops[base],
- u_color_stops[base + 1],
- u_color_stops[base + 2],
- u_color_stops[base + 3]);
-}
-
-void main() {
- float offset = dot(info.xy, info.zw);
-
- if (u_repeat) {
- offset = fract(offset);
- }
-
- if (offset < get_offset(0)) {
- gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
- return;
- }
-
- int n = u_num_color_stops - 1;
- for (int i = 0; i < n; i++) {
- float curr_offset = get_offset(i);
- float next_offset = get_offset(i + 1);
-
- if (offset >= curr_offset && offset < next_offset) {
- float f = (offset - curr_offset) / (next_offset - curr_offset);
- vec4 curr_color = gsk_premultiply(get_color(i));
- vec4 next_color = gsk_premultiply(get_color(i + 1));
- vec4 color = mix(curr_color, next_color, f);
-
- gskSetOutputColor(color * u_alpha);
- return;
- }
- }
-
- gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
-}
+++ /dev/null
-// VERTEX_SHADER:
-uniform vec4 u_color;
-uniform vec4[3] u_outline_rect;
-
-_OUT_ vec4 final_color;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outline;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-
- GskRoundedRect outline = gsk_create_rect(u_outline_rect);
- gsk_rounded_rect_transform(outline, u_modelview);
- gsk_rounded_rect_encode(outline, transformed_outline);
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec4 final_color;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outline;
-
-void main() {
- vec2 frag = gsk_get_frag_coord();
-
- float alpha = GskTexture(u_source, vUv).a;
- alpha *= (1.0 - clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outline), frag), 0.0, 1.0));
-
- vec4 color = final_color * alpha;
-
- gskSetOutputColor(color);
-}
+++ /dev/null
-uniform sampler2D u_source;
-uniform mat4 u_projection;
-uniform mat4 u_modelview;
-uniform float u_alpha;// = 1.0;
-uniform vec4 u_viewport;
-uniform vec4[3] u_clip_rect;
-
-#if defined(GSK_LEGACY)
-_OUT_ vec4 outputColor;
-#elif !defined(GSK_GLES)
-_OUT_ vec4 outputColor;
-#endif
-
-_IN_ vec2 vUv;
-
-
-
-GskRoundedRect gsk_decode_rect(_GSK_ROUNDED_RECT_UNIFORM_ r)
-{
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
- return GskRoundedRect(r[0], r[1], r[2]);
-#else
- return r;
-#endif
-}
-
-float
-gsk_ellipsis_dist (vec2 p, vec2 radius)
-{
- if (radius == vec2(0, 0))
- return 0.0;
-
- vec2 p0 = p / radius;
- vec2 p1 = 2.0 * p0 / radius;
-
- return (dot(p0, p0) - 1.0) / length (p1);
-}
-
-float
-gsk_ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
-{
- float d = gsk_ellipsis_dist (point - center, radius);
- return clamp (0.5 - d, 0.0, 1.0);
-}
-
-float
-gsk_rounded_rect_coverage (GskRoundedRect r, vec2 p)
-{
- if (p.x < r.bounds.x || p.y < r.bounds.y ||
- p.x >= r.bounds.z || p.y >= r.bounds.w)
- return 0.0;
-
- vec2 ref_tl = r.corner_points1.xy;
- vec2 ref_tr = r.corner_points1.zw;
- vec2 ref_br = r.corner_points2.xy;
- vec2 ref_bl = r.corner_points2.zw;
-
- if (p.x >= ref_tl.x && p.x >= ref_bl.x &&
- p.x <= ref_tr.x && p.x <= ref_br.x)
- return 1.0;
-
- if (p.y >= ref_tl.y && p.y >= ref_tr.y &&
- p.y <= ref_bl.y && p.y <= ref_br.y)
- return 1.0;
-
- vec2 rad_tl = r.corner_points1.xy - r.bounds.xy;
- vec2 rad_tr = r.corner_points1.zw - r.bounds.zy;
- vec2 rad_br = r.corner_points2.xy - r.bounds.zw;
- vec2 rad_bl = r.corner_points2.zw - r.bounds.xw;
-
- float d_tl = gsk_ellipsis_coverage(p, ref_tl, rad_tl);
- float d_tr = gsk_ellipsis_coverage(p, ref_tr, rad_tr);
- float d_br = gsk_ellipsis_coverage(p, ref_br, rad_br);
- float d_bl = gsk_ellipsis_coverage(p, ref_bl, rad_bl);
-
- vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
-
- bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
- p.x > ref_tr.x && p.y < ref_tr.y,
- p.x > ref_br.x && p.y > ref_br.y,
- p.x < ref_bl.x && p.y > ref_bl.y);
-
- return 1.0 - dot(vec4(is_out), corner_coverages);
-}
-
-float
-gsk_rect_coverage (vec4 r, vec2 p)
-{
- if (p.x < r.x || p.y < r.y ||
- p.x >= r.z || p.y >= r.w)
- return 0.0;
-
- return 1.0;
-}
-
-vec4 GskTexture(sampler2D sampler, vec2 texCoords) {
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
- return texture2D(sampler, texCoords);
-#else
- return texture(sampler, texCoords);
-#endif
-}
-
-#ifdef GSK_GL3
-layout(origin_upper_left) in vec4 gl_FragCoord;
-#endif
-
-vec2 gsk_get_frag_coord() {
- vec2 fc = gl_FragCoord.xy;
-
-#ifdef GSK_GL3
- fc += u_viewport.xy;
-#else
- fc.x += u_viewport.x;
- fc.y = (u_viewport.y + u_viewport.w) - fc.y;
-#endif
-
- return fc;
-}
-
-void gskSetOutputColor(vec4 color) {
- vec4 result;
-
-#if defined(NO_CLIP)
- result = color;
-#elif defined(RECT_CLIP)
- result = color * gsk_rect_coverage(gsk_get_bounds(u_clip_rect),
- gsk_get_frag_coord());
-#else
- result = color * gsk_rounded_rect_coverage(gsk_create_rect(u_clip_rect),
- gsk_get_frag_coord());
-#endif
-
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
- gl_FragColor = result;
-#else
- outputColor = result;
-#endif
-}
+++ /dev/null
-#ifndef GSK_LEGACY
-precision highp float;
-#endif
-
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
-#define _OUT_ varying
-#define _IN_ varying
-#define _NOPERSPECTIVE_
-#define _GSK_ROUNDED_RECT_UNIFORM_ vec4[3]
-#else
-#define _OUT_ out
-#define _IN_ in
-#define _NOPERSPECTIVE_ noperspective
-#define _GSK_ROUNDED_RECT_UNIFORM_ GskRoundedRect
-#endif
-
-
-struct GskRoundedRect
-{
- vec4 bounds; // Top left and bottom right
- // Look, arrays can't be in structs if you want to return the struct
- // from a function in gles or whatever. Just kill me.
- vec4 corner_points1; // xy = top left, zw = top right
- vec4 corner_points2; // xy = bottom right, zw = bottom left
-};
-
-// Transform from a C GskRoundedRect to what we need.
-GskRoundedRect
-gsk_create_rect(vec4[3] data)
-{
- vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
-
- vec4 corner_points1 = vec4(bounds.xy + data[1].xy,
- bounds.zy + vec2(data[1].zw * vec2(-1, 1)));
- vec4 corner_points2 = vec4(bounds.zw + (data[2].xy * vec2(-1, -1)),
- bounds.xw + vec2(data[2].zw * vec2(1, -1)));
-
- return GskRoundedRect(bounds, corner_points1, corner_points2);
-}
-
-vec4
-gsk_get_bounds(vec4[3] data)
-{
- return vec4(data[0].xy, data[0].xy + data[0].zw);
-}
-
-vec4 gsk_premultiply(vec4 c) {
- return vec4(c.rgb * c.a, c.a);
-}
-
-vec4 gsk_scaled_premultiply(vec4 c, float s) {
- // Fast version of gsk_premultiply(c) * s
- // 4 muls instead of 7
- float a = s * c.a;
-
- return vec4(c.rgb * a, a);
-}
+++ /dev/null
-uniform mat4 u_projection;
-uniform mat4 u_modelview;
-uniform float u_alpha;
-
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
-attribute vec2 aPosition;
-attribute vec2 aUv;
-_OUT_ vec2 vUv;
-#else
-_IN_ vec2 aPosition;
-_IN_ vec2 aUv;
-_OUT_ vec2 vUv;
-#endif
-
-// amount is: top, right, bottom, left
-GskRoundedRect
-gsk_rounded_rect_shrink (GskRoundedRect r, vec4 amount)
-{
- vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
- vec4 new_corner_points1 = r.corner_points1;
- vec4 new_corner_points2 = r.corner_points2;
-
- if (r.corner_points1.xy == r.bounds.xy) new_corner_points1.xy = new_bounds.xy;
- if (r.corner_points1.zw == r.bounds.zy) new_corner_points1.zw = new_bounds.zy;
- if (r.corner_points2.xy == r.bounds.zw) new_corner_points2.xy = new_bounds.zw;
- if (r.corner_points2.zw == r.bounds.xw) new_corner_points2.zw = new_bounds.xw;
-
- return GskRoundedRect (new_bounds, new_corner_points1, new_corner_points2);
-}
-
-void
-gsk_rounded_rect_offset(inout GskRoundedRect r, vec2 offset)
-{
- r.bounds.xy += offset;
- r.bounds.zw += offset;
- r.corner_points1.xy += offset;
- r.corner_points1.zw += offset;
- r.corner_points2.xy += offset;
- r.corner_points2.zw += offset;
-}
-
-void gsk_rounded_rect_transform(inout GskRoundedRect r, mat4 mat)
-{
- r.bounds.xy = (mat * vec4(r.bounds.xy, 0.0, 1.0)).xy;
- r.bounds.zw = (mat * vec4(r.bounds.zw, 0.0, 1.0)).xy;
-
- r.corner_points1.xy = (mat * vec4(r.corner_points1.xy, 0.0, 1.0)).xy;
- r.corner_points1.zw = (mat * vec4(r.corner_points1.zw, 0.0, 1.0)).xy;
-
- r.corner_points2.xy = (mat * vec4(r.corner_points2.xy, 0.0, 1.0)).xy;
- r.corner_points2.zw = (mat * vec4(r.corner_points2.zw, 0.0, 1.0)).xy;
-}
-
-#if defined(GSK_LEGACY)
-// Can't have out or inout array parameters...
-#define gsk_rounded_rect_encode(r, uni) uni[0] = r.bounds; uni[1] = r.corner_points1; uni[2] = r.corner_points2;
-#else
-void gsk_rounded_rect_encode(GskRoundedRect r, out _GSK_ROUNDED_RECT_UNIFORM_ out_r)
-{
-#if defined(GSK_GLES)
- out_r[0] = r.bounds;
- out_r[1] = r.corner_points1;
- out_r[2] = r.corner_points2;
-#else
- out_r = r;
-#endif
-}
-
-#endif
+++ /dev/null
-// VERTEX_SHADER
-uniform vec4 u_geometry;
-
-_NOPERSPECTIVE_ _OUT_ vec2 coord;
-
-void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
-
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
- vec2 offset = aPosition - u_geometry.xy;
- vec2 dir = vec2(dot(mv0, offset),
- dot(mv1, offset));
-
- coord = dir * u_geometry.zw;
-}
-
-// FRAGMENT_SHADER:
-#ifdef GSK_LEGACY
-uniform int u_num_color_stops;
-#else
-uniform highp int u_num_color_stops;
-#endif
-
-uniform bool u_repeat;
-uniform vec2 u_range;
-uniform float u_color_stops[6 * 5];
-
-_NOPERSPECTIVE_ _IN_ vec2 coord;
-
-float get_offset(int index) {
- return u_color_stops[5 * index];
-}
-
-vec4 get_color(int index) {
- int base = 5 * index + 1;
-
- return vec4(u_color_stops[base],
- u_color_stops[base + 1],
- u_color_stops[base + 2],
- u_color_stops[base + 3]);
-}
-
-void main() {
- // Reverse scale
- float offset = length(coord) * u_range.x + u_range.y;
-
- if (u_repeat) {
- offset = fract(offset);
- }
-
- if (offset < get_offset(0)) {
- gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
- return;
- }
-
- int n = u_num_color_stops - 1;
- for (int i = 0; i < n; i++) {
- float curr_offset = get_offset(i);
- float next_offset = get_offset(i + 1);
-
- if (offset >= curr_offset && offset < next_offset) {
- float f = (offset - curr_offset) / (next_offset - curr_offset);
- vec4 curr_color = gsk_premultiply(get_color(i));
- vec4 next_color = gsk_premultiply(get_color(i + 1));
- vec4 color = mix(curr_color, next_color, f);
-
- gskSetOutputColor(color * u_alpha);
- return;
- }
- }
-
- gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
-}
+++ /dev/null
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-uniform vec4 u_child_bounds;
-uniform vec4 u_texture_rect;
-
-
-float wrap(float f, float wrap_for) {
- return mod(f, wrap_for);
-}
-
-/* We get the texture coordinates via vUv,
- * but that might be on a texture atlas, so we need to do the
- * wrapping ourselves.
- */
-void main() {
-
- /* We map the texture coordinate to [1;0], then wrap it and scale the result again */
-
- float tw = u_texture_rect.z - u_texture_rect.x;
- float th = u_texture_rect.w - u_texture_rect.y;
-
- float mapped_x = (vUv.x - u_texture_rect.x) / tw;
- float mapped_y = (vUv.y - u_texture_rect.y) / th;
-
- float wrapped_x = wrap(u_child_bounds.x + mapped_x * u_child_bounds.z, 1.0);
- float wrapped_y = wrap(u_child_bounds.y + mapped_y * u_child_bounds.w, 1.0);
-
- vec2 tp;
- tp.x = u_texture_rect.x + (wrapped_x * tw);
- tp.y = u_texture_rect.y + (wrapped_y * th);
-
- vec4 diffuse = GskTexture(u_source, tp);
-
- gskSetOutputColor(diffuse * u_alpha);
-}
+++ /dev/null
-// VERTEX_SHADER:
-uniform vec4 u_color;
-uniform float u_spread;
-uniform vec2 u_offset;
-uniform vec4[3] u_outline_rect;
-
-_OUT_ vec4 final_color;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-
- GskRoundedRect inside = gsk_create_rect(u_outline_rect);
- GskRoundedRect outside = gsk_rounded_rect_shrink(inside, vec4(- u_spread));
-
- gsk_rounded_rect_offset(outside, u_offset);
-
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
-
- gsk_rounded_rect_encode(outside, transformed_outside_outline);
- gsk_rounded_rect_encode(inside, transformed_inside_outline);
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec4 final_color;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- vec2 frag = gsk_get_frag_coord();
-
- float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
- gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
- 0.0, 1.0);
-
- gskSetOutputColor(final_color * alpha);
-}
-
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in vec2 inStartTexCoord;
-layout(location = 2) in vec2 inEndTexCoord;
-layout(location = 3) flat in uint inBlendMode;
-
-layout(set = 0, binding = 0) uniform sampler2D startTexture;
-layout(set = 1, binding = 0) uniform sampler2D endTexture;
-
-layout(location = 0) out vec4 outColor;
-
-float
-combine (float source, float backdrop)
-{
- return source + backdrop * (1 - source);
-}
-
-vec4
-composite (vec4 Cs, vec4 Cb, vec3 B)
-{
- float ao = Cs.a + Cb.a * (1 - Cs.a);
- vec3 Co = (Cs.a*(1 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1 - Cs.a)*Cb.a*Cb.rgb) / ao;
- return vec4(Co, ao);
-}
-
-vec4
-normal (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb);
-}
-
-vec4
-multiply (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb * Cb.rgb);
-}
-
-vec4
-difference (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, abs(Cs.rgb - Cb.rgb));
-}
-
-vec4
-screen (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb + Cb.rgb - Cs.rgb * Cb.rgb);
-}
-
-float
-hard_light (float source, float backdrop)
-{
- if (source <= 0.5)
- return 2 * backdrop * source;
- else
- return 2 * (backdrop + source - backdrop * source) - 1;
-}
-
-vec4
-hard_light (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (hard_light (Cs.r, Cb.r),
- hard_light (Cs.g, Cb.g),
- hard_light (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-float
-soft_light (float source, float backdrop)
-{
- float db;
-
- if (backdrop <= 0.25)
- db = ((16 * backdrop - 12) * backdrop + 4) * backdrop;
- else
- db = sqrt (backdrop);
-
- if (source <= 0.5)
- return backdrop - (1 - 2 * source) * backdrop * (1 - backdrop);
- else
- return backdrop + (2 * source - 1) * (db - backdrop);
-}
-
-vec4
-soft_light (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (soft_light (Cs.r, Cb.r),
- soft_light (Cs.g, Cb.g),
- soft_light (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-overlay (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (hard_light (Cb.r, Cs.r),
- hard_light (Cb.g, Cs.g),
- hard_light (Cb.b, Cs.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-darken (vec4 Cs, vec4 Cb)
-{
- vec3 B = min (Cs.rgb, Cb.rgb);
- return composite (Cs, Cb, B);
-}
-
-vec4
-lighten (vec4 Cs, vec4 Cb)
-{
- vec3 B = max (Cs.rgb, Cb.rgb);
- return composite (Cs, Cb, B);
-}
-
-float
-color_dodge (float source, float backdrop)
-{
- return (source == 1.0) ? source : min (backdrop / (1.0 - source), 1.0);
-}
-
-vec4
-color_dodge (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (color_dodge (Cs.r, Cb.r),
- color_dodge (Cs.g, Cb.g),
- color_dodge (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-
-float
-color_burn (float source, float backdrop)
-{
- return (source == 0.0) ? source : max ((1.0 - ((1.0 - backdrop) / source)), 0.0);
-}
-
-vec4
-color_burn (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (color_burn (Cs.r, Cb.r),
- color_burn (Cs.g, Cb.g),
- color_burn (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-exclusion (vec4 Cs, vec4 Cb)
-{
- vec3 B = Cb.rgb + Cs.rgb - 2.0 * Cb.rgb * Cs.rgb;
- return composite (Cs, Cb, B);
-}
-
-float
-lum (vec3 c)
-{
- return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
-}
-
-vec3
-clip_color (vec3 c)
-{
- float l = lum (c);
- float n = min (c.r, min (c.g, c.b));
- float x = max (c.r, max (c.g, c.b));
- if (n < 0) c = l + (((c - l) * l) / (l - n));
- if (x > 1) c = l + (((c - l) * (1 - l)) / (x - l));
- return c;
-}
-
-vec3
-set_lum (vec3 c, float l)
-{
- float d = l - lum (c);
- return clip_color (vec3 (c.r + d, c.g + d, c.b + d));
-}
-
-float
-sat (vec3 c)
-{
- return max (c.r, max (c.g, c.b)) - min (c.r, min (c.g, c.b));
-}
-
-vec3
-set_sat (vec3 c, float s)
-{
- float cmin = min (c.r, min (c.g, c.b));
- float cmax = max (c.r, max (c.g, c.b));
- vec3 res;
-
- if (cmax == cmin)
- res = vec3 (0, 0, 0);
- else
- {
- if (c.r == cmax)
- {
- if (c.g == cmin)
- {
- res.b = ((c.b - cmin) * s) / (cmax - cmin);
- res.g = 0;
- }
- else
- {
- res.g = ((c.g - cmin) * s) / (cmax - cmin);
- res.b = 0;
- }
- res.r = s;
- }
- else if (c.g == cmax)
- {
- if (c.r == cmin)
- {
- res.b = ((c.b - cmin) * s) / (cmax - cmin);
- res.r = 0;
- }
- else
- {
- res.r = ((c.r - cmin) * s) / (cmax - cmin);
- res.b = 0;
- }
- res.g = s;
- }
- else
- {
- if (c.r == cmin)
- {
- res.g = ((c.g - cmin) * s) / (cmax - cmin);
- res.r = 0;
- }
- else
- {
- res.r = ((c.r - cmin) * s) / (cmax - cmin);
- res.g = 0;
- }
- res.b = s;
- }
- }
- return res;
-}
-
-vec4
-color (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (Cs.rgb, lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-hue (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (set_sat (Cs.rgb, sat (Cb.rgb)), lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-saturation (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (set_sat (Cb.rgb, sat (Cs.rgb)), lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-luminosity (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (Cb.rgb, lum (Cs.rgb));
- return composite (Cs, Cb, B);
-}
-
-void main()
-{
- vec4 source = texture (startTexture, inStartTexCoord);
- vec4 backdrop = texture (endTexture, inEndTexCoord);
- vec4 result;
-
- if (inBlendMode == 0)
- result = normal (source, backdrop);
- else if (inBlendMode == 1)
- result = multiply (source, backdrop);
- else if (inBlendMode == 2)
- result = screen (source, backdrop);
- else if (inBlendMode == 3)
- result = overlay (source, backdrop);
- else if (inBlendMode == 4)
- result = darken (source, backdrop);
- else if (inBlendMode == 5)
- result = lighten (source, backdrop);
- else if (inBlendMode == 6)
- result = color_dodge (source, backdrop);
- else if (inBlendMode == 7)
- result = color_burn (source, backdrop);
- else if (inBlendMode == 8)
- result = hard_light (source, backdrop);
- else if (inBlendMode == 9)
- result = soft_light (source, backdrop);
- else if (inBlendMode == 10)
- result = difference (source, backdrop);
- else if (inBlendMode == 11)
- result = exclusion (source, backdrop);
- else if (inBlendMode == 12)
- result = color (source, backdrop);
- else if (inBlendMode == 13)
- result = hue (source, backdrop);
- else if (inBlendMode == 14)
- result = saturation (source, backdrop);
- else if (inBlendMode == 15)
- result = luminosity (source, backdrop);
- else
- discard;
-
- outColor = clip (inPos, result);
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec4 inStartTexRect;
-layout(location = 2) in vec4 inEndTexRect;
-layout(location = 3) in uint inBlendMode;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out vec2 outStartTexCoord;
-layout(location = 2) out vec2 outEndTexCoord;
-layout(location = 3) flat out uint outBlendMode;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-void main() {
- vec4 rect = clip (inRect);
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
-
- outPos = pos;
-
- vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
- rect.zw / inRect.zw);
- vec4 starttexrect = vec4(inStartTexRect.xy + inStartTexRect.zw * texrect.xy,
- inStartTexRect.zw * texrect.zw);
- vec4 endtexrect = vec4(inEndTexRect.xy + inEndTexRect.zw * texrect.xy,
- inEndTexRect.zw * texrect.zw);
-
- outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex];
- outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex];
-
- outBlendMode = inBlendMode;
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in flat vec2 inSize;
-layout(location = 2) in vec2 inTexCoord;
-layout(location = 3) in float inRadius;
-
-layout(set = 0, binding = 0) uniform sampler2D inTexture;
-
-layout(location = 0) out vec4 color;
-
-const int samples_x = 15; // must be odd
-const int samples_y = 15; // must be odd
-
-const int half_samples_x = samples_x / 2;
-const int half_samples_y = samples_y / 2;
-
-float Gaussian (float sigma, float x)
-{
- return exp ( - (x * x) / (2.0 * sigma * sigma));
-}
-
-vec4 blur_pixel (in vec2 uv)
-{
- float total = 0.0;
- vec4 ret = vec4 (0);
- float pixel_size_x = (1.0 / inSize.x);
- float pixel_size_y = (1.0 / inSize.y);
-
- for (int y = 0; y < samples_y; ++y)
- {
- float fy = Gaussian (inRadius, float(y) - float(half_samples_x));
- float offset_y = float(y - half_samples_y) * pixel_size_y;
- for (int x = 0; x < samples_x; ++x)
- {
- float fx = Gaussian (inRadius, float(x) - float(half_samples_x));
- float offset_x = float(x - half_samples_x) * pixel_size_x;
- total += fx * fy;
- ret += texture(inTexture, uv + vec2(offset_x, offset_y)) * fx * fy;
- }
- }
- return ret / total;
-}
-
-void main()
-{
- color = clip (inPos, blur_pixel (inTexCoord));
-}
+++ /dev/null
-
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec4 inTexRect;
-layout(location = 2) in float inRadius;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out flat vec2 outSize;
-layout(location = 2) out vec2 outTexCoord;
-layout(location = 3) out flat float outRadius;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-void main() {
- vec4 rect = clip (inRect);
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
-
- outPos = pos;
- outSize = inRect.zw;
-
- vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
- rect.zw / inRect.zw);
- texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
- inTexRect.zw * texrect.zw);
- outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
-
- outRadius = inRadius;
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-#include "rounded-rect.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in vec4 inColor;
-layout(location = 2) in vec4 inRect;
-layout(location = 3) in vec4 inCornerWidths;
-layout(location = 4) in vec4 inCornerHeights;
-layout(location = 5) in vec4 inBorderWidths;
-
-layout(location = 0) out vec4 color;
-
-void main()
-{
- RoundedRect routside = RoundedRect (vec4(inRect.xy, inRect.xy + inRect.zw), inCornerWidths, inCornerHeights);
- RoundedRect rinside = rounded_rect_shrink (routside, inBorderWidths);
-
- float alpha = clamp (rounded_rect_coverage (routside, inPos) -
- rounded_rect_coverage (rinside, inPos),
- 0.0, 1.0);
- color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a) * alpha);
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec4 inCornerWidths;
-layout(location = 2) in vec4 inCornerHeights;
-layout(location = 3) in vec4 inBorderWidths;
-layout(location = 4) in mat4 inBorderColors;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out flat vec4 outColor;
-layout(location = 2) out flat vec4 outRect;
-layout(location = 3) out flat vec4 outCornerWidths;
-layout(location = 4) out flat vec4 outCornerHeights;
-layout(location = 5) out flat vec4 outBorderWidths;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(1.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0) };
-
-#define TOP 0
-#define RIGHT 1
-#define BOTTOM 2
-#define LEFT 3
-
-#define TOP_LEFT 0
-#define TOP_RIGHT 1
-#define BOTTOM_RIGHT 2
-#define BOTTOM_LEFT 3
-
-#define SLICE_TOP_LEFT 0
-#define SLICE_TOP 1
-#define SLICE_TOP_RIGHT 2
-#define SLICE_RIGHT 3
-#define SLICE_BOTTOM_RIGHT 4
-#define SLICE_BOTTOM 5
-#define SLICE_BOTTOM_LEFT 6
-#define SLICE_LEFT 7
-
-void main() {
- int slice_index = gl_VertexIndex / 6;
- int vert_index = gl_VertexIndex % 6;
-
- vec4 corner_widths = max (inCornerWidths, inBorderWidths.wyyw);
- vec4 corner_heights = max (inCornerHeights, inBorderWidths.xxzz);
-
- vec4 rect;
-
- switch (slice_index)
- {
- case SLICE_TOP_LEFT:
- rect = vec4(inRect.xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]);
- vert_index = (vert_index + 3) % 6;
- break;
- case SLICE_TOP:
- rect = vec4(inRect.x + corner_widths[TOP_LEFT], inRect.y, inRect.z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[TOP]);
- outColor = inBorderColors[TOP];
- break;
- case SLICE_TOP_RIGHT:
- rect = vec4(inRect.x + inRect.z - corner_widths[TOP_RIGHT], inRect.y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]);
- break;
- case SLICE_RIGHT:
- rect = vec4(inRect.x + inRect.z - inBorderWidths[RIGHT], inRect.y + corner_heights[TOP_RIGHT], inBorderWidths[RIGHT], inRect.w - corner_heights[TOP_RIGHT] - corner_heights[BOTTOM_RIGHT]);
- outColor = inBorderColors[RIGHT];
- break;
- case SLICE_BOTTOM_RIGHT:
- rect = vec4(inRect.x + inRect.z - corner_widths[BOTTOM_RIGHT], inRect.y + inRect.w - corner_heights[BOTTOM_RIGHT], corner_widths[BOTTOM_RIGHT], corner_heights[BOTTOM_RIGHT]);
- break;
- case SLICE_BOTTOM:
- rect = vec4(inRect.x + corner_widths[BOTTOM_LEFT], inRect.y + inRect.w - inBorderWidths[BOTTOM], inRect.z - corner_widths[BOTTOM_LEFT] - corner_widths[BOTTOM_RIGHT], inBorderWidths[BOTTOM]);
- break;
- case SLICE_BOTTOM_LEFT:
- rect = vec4(inRect.x, inRect.y + inRect.w - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], corner_heights[BOTTOM_LEFT]);
- vert_index = (vert_index + 3) % 6;
- break;
- case SLICE_LEFT:
- rect = vec4(inRect.x, inRect.y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect.w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_LEFT]);
- break;
- }
-
- rect = clip (rect);
- vec2 pos;
- if ((slice_index % 4) != 0 || (vert_index % 3) != 2)
- pos = rect.xy + rect.zw * offsets[vert_index];
- else
- pos = rect.xy + rect.zw * vec2(1.0 - offsets[vert_index].x, offsets[vert_index].y);
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
- outColor = inBorderColors[((gl_VertexIndex / 3 + 15) / 4) % 4];
- outPos = pos;
- outRect = inRect;
- outCornerWidths = inCornerWidths;
- outCornerHeights = inCornerHeights;
- outBorderWidths = inBorderWidths;
-}
+++ /dev/null
-#include "constants.glsl"
-#include "rounded-rect.glsl"
-
-#ifndef _CLIP_
-#define _CLIP_
-
-#ifdef CLIP_ROUNDED_RECT
-vec4 clip(vec2 pos, vec4 color)
-{
- RoundedRect r = RoundedRect(vec4(push.clip_bounds.xy, push.clip_bounds.xy + push.clip_bounds.zw), push.clip_widths, push.clip_heights);
-
- return color * rounded_rect_coverage (r, pos);
-}
-#elif defined(CLIP_RECT)
-vec4 clip(vec2 pos, vec4 color)
-{
- /* clipped in vertex shader already */
- return color;
-}
-#elif defined(CLIP_NONE)
-vec4 clip(vec2 pos, vec4 color)
-{
- return color;
-}
-#else
-#error "No clipping define given. Need CLIP_NONE, CLIP_RECT or CLIP_ROUNDED_RECT"
-#endif
-
-#endif
+++ /dev/null
-#include "constants.glsl"
-
-#ifndef _CLIP_
-#define _CLIP_
-
-vec4 intersect(vec4 a, vec4 b)
-{
- a = vec4(a.xy, a.xy + a.zw);
- b = vec4(b.xy, b.xy + b.zw);
- vec4 result = vec4(max(a.xy, b.xy), min(a.zw, b.zw));
- if (any (greaterThanEqual (result.xy, result.zw)))
- return vec4(0.0,0.0,0.0,0.0);
- return vec4(result.xy, result.zw - result.xy);
-}
-
-#ifdef CLIP_ROUNDED_RECT
-vec4 clip(vec4 rect)
-{
- /* rounded corner clipping is done in fragment shader */
- return intersect(rect, push.clip_bounds);
-}
-#elif defined(CLIP_RECT)
-vec4 clip(vec4 rect)
-{
- return intersect(rect, push.clip_bounds);
-}
-#elif defined(CLIP_NONE)
-vec4 clip(vec4 rect)
-{
- return rect;
-}
-#else
-#error "No clipping define given. Need CLIP_NONE, CLIP_RECT or CLIP_ROUNDED_RECT"
-#endif
-
-#endif
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in vec2 inTexCoord;
-layout(location = 2) in flat mat4 inColorMatrix;
-layout(location = 6) in flat vec4 inColorOffset;
-
-layout(set = 0, binding = 0) uniform sampler2D inTexture;
-
-layout(location = 0) out vec4 color;
-
-vec4
-color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset)
-{
- /* unpremultiply */
- if (color.a != 0.0)
- color.rgb /= color.a;
-
- color = color_matrix * color + color_offset;
- color = clamp(color, 0.0, 1.0);
-
- /* premultiply */
- color.rgb *= color.a;
-
- return color;
-}
-
-void main()
-{
- color = clip (inPos, color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset));
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec4 inTexRect;
-layout(location = 2) in mat4 inColorMatrix;
-layout(location = 6) in vec4 inColorOffset;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out vec2 outTexCoord;
-layout(location = 2) out flat mat4 outColorMatrix;
-layout(location = 6) out flat vec4 outColorOffset;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-void main() {
- vec4 rect = clip (inRect);
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
-
- outPos = pos;
-
- vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
- rect.zw / inRect.zw);
- texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
- inTexRect.zw * texrect.zw);
- outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
- outColorMatrix = inColorMatrix;
- outColorOffset = inColorOffset;
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in vec4 inColor;
-
-layout(location = 0) out vec4 color;
-
-void main()
-{
- color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a));
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec4 inColor;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out flat vec4 outColor;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-void main() {
- vec4 rect = clip (inRect);
-
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
- outPos = pos;
- outColor = inColor;
-}
+++ /dev/null
-#ifndef _CONSTANTS_
-#define _CONSTANTS_
-
-layout(push_constant) uniform PushConstants {
- mat4 mvp;
- vec4 clip_bounds;
- vec4 clip_widths;
- vec4 clip_heights;
-} push;
-
-#endif
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in vec2 inStartTexCoord;
-layout(location = 2) in vec2 inEndTexCoord;
-layout(location = 3) in float inProgress;
-
-layout(set = 0, binding = 0) uniform sampler2D startTexture;
-layout(set = 1, binding = 0) uniform sampler2D endTexture;
-
-layout(location = 0) out vec4 color;
-
-void main()
-{
- vec4 start = texture (startTexture, inStartTexCoord);
- vec4 end = texture (endTexture, inEndTexCoord);
-
- color = clip (inPos, mix (start, end, inProgress));
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec4 inStartTexRect;
-layout(location = 2) in vec4 inEndTexRect;
-layout(location = 3) in float inProgress;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out vec2 outStartTexCoord;
-layout(location = 2) out vec2 outEndTexCoord;
-layout(location = 3) out float outProgress;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-void main() {
- vec4 rect = clip (inRect);
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
-
- outPos = pos;
-
- vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
- rect.zw / inRect.zw);
- vec4 starttexrect = vec4(inStartTexRect.xy + inStartTexRect.zw * texrect.xy,
- inStartTexRect.zw * texrect.zw);
- vec4 endtexrect = vec4(inEndTexRect.xy + inEndTexRect.zw * texrect.xy,
- inEndTexRect.zw * texrect.zw);
-
- outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex];
- outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex];
-
- outProgress = inProgress;
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-#include "rounded-rect.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in flat vec4 inOutline;
-layout(location = 2) in flat vec4 inOutlineCornerWidths;
-layout(location = 3) in flat vec4 inOutlineCornerHeights;
-layout(location = 4) in flat vec4 inColor;
-layout(location = 5) in flat vec2 inOffset;
-layout(location = 6) in flat float inSpread;
-
-layout(location = 0) out vec4 color;
-
-void main()
-{
- RoundedRect outline = RoundedRect (vec4(inOutline.xy, inOutline.xy + inOutline.zw), inOutlineCornerWidths, inOutlineCornerHeights);
- RoundedRect inside = rounded_rect_shrink (outline, vec4(inSpread));
-
- color = vec4(inColor.rgb * inColor.a, inColor.a);
- color = color * clamp (rounded_rect_coverage (outline, inPos) -
- rounded_rect_coverage (inside, inPos - inOffset),
- 0.0, 1.0);
- color = clip (inPos, color);
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inOutline;
-layout(location = 1) in vec4 inOutlineCornerWidths;
-layout(location = 2) in vec4 inOutlineCornerHeights;
-layout(location = 3) in vec4 inColor;
-layout(location = 4) in vec2 inOffset;
-layout(location = 5) in float inSpread;
-layout(location = 6) in float inBlurRadius;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out flat vec4 outOutline;
-layout(location = 2) out flat vec4 outOutlineCornerWidths;
-layout(location = 3) out flat vec4 outOutlineCornerHeights;
-layout(location = 4) out flat vec4 outColor;
-layout(location = 5) out flat vec2 outOffset;
-layout(location = 6) out flat float outSpread;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-void main() {
- vec4 rect = clip (inOutline);
-
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
- outPos = pos;
-
- outOutline = inOutline;
- outOutlineCornerWidths = inOutlineCornerWidths;
- outOutlineCornerHeights = inOutlineCornerHeights;
- outColor = inColor;
- outOffset = inOffset;
- outSpread = inSpread;
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-
-struct ColorStop {
- float offset;
- vec4 color;
-};
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in float inGradientPos;
-layout(location = 2) in flat int inRepeating;
-layout(location = 3) in flat int inStopCount;
-layout(location = 4) in flat ColorStop inStops[8];
-
-layout(location = 0) out vec4 outColor;
-
-void main()
-{
- float pos;
- if (inRepeating != 0)
- pos = fract (inGradientPos);
- else
- pos = clamp (inGradientPos, 0, 1);
-
- vec4 color = inStops[0].color;
- int n = clamp (inStopCount, 2, 8);
- for (int i = 1; i < n; i++)
- {
- if (inStops[i].offset > inStops[i-1].offset)
- color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
- }
-
- //outColor = vec4(pos, pos, pos, 1.0);
- outColor = clip (inPos, color);
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-struct ColorStop {
- float offset;
- vec4 color;
-};
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec2 inStart;
-layout(location = 2) in vec2 inEnd;
-layout(location = 3) in int inRepeating;
-layout(location = 4) in int inStopCount;
-layout(location = 5) in vec4 inOffsets0;
-layout(location = 6) in vec4 inOffsets1;
-layout(location = 7) in vec4 inColors0;
-layout(location = 8) in vec4 inColors1;
-layout(location = 9) in vec4 inColors2;
-layout(location = 10) in vec4 inColors3;
-layout(location = 11) in vec4 inColors4;
-layout(location = 12) in vec4 inColors5;
-layout(location = 13) in vec4 inColors6;
-layout(location = 14) in vec4 inColors7;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out float outGradientPos;
-layout(location = 2) out flat int outRepeating;
-layout(location = 3) out flat int outStopCount;
-layout(location = 4) out flat ColorStop outStops[8];
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-float
-get_gradient_pos (vec2 pos)
-{
- pos = pos - inStart;
- vec2 grad = inEnd - inStart;
-
- return dot (pos, grad) / dot (grad, grad);
-}
-
-void main() {
- vec4 rect = clip (inRect);
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
- outPos = pos;
- outGradientPos = get_gradient_pos (pos);
- outRepeating = inRepeating;
- outStopCount = inStopCount;
- outStops[0].offset = inOffsets0[0];
- outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
- outStops[1].offset = inOffsets0[1];
- outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
- outStops[2].offset = inOffsets0[2];
- outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
- outStops[3].offset = inOffsets0[3];
- outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
- outStops[4].offset = inOffsets1[0];
- outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
- outStops[5].offset = inOffsets1[1];
- outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
- outStops[6].offset = inOffsets1[2];
- outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
- outStops[7].offset = inOffsets1[3];
- outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in vec2 inTexCoord;
-layout(location = 2) in vec4 inColor;
-
-layout(set = 0, binding = 0) uniform sampler2D inTexture;
-
-layout(location = 0) out vec4 color;
-
-void main()
-{
- color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a) * texture(inTexture, inTexCoord).a);
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec4 inTexRect;
-layout(location = 2) in vec4 inColor;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out vec2 outTexCoord;
-layout(location = 2) out flat vec4 outColor;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-void main() {
- vec4 rect = clip (inRect);
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
-
- outPos = pos;
-
- vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
- rect.zw / inRect.zw);
- texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
- inTexRect.zw * texrect.zw);
- outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
-
- outColor = inColor;
-}
+++ /dev/null
-# FIXME: what's up with these?
-#gsk_private_vulkan_include_shaders = [
-# 'clip.frag.glsl',
-# 'clip.vert.glsl',
-# 'constants.glsl',
-# 'rounded-rect.glsl',
-#]
-
-gsk_private_vulkan_fragment_shaders = [
- 'blendmode.frag',
- 'blur.frag',
- 'border.frag',
- 'color.frag',
- 'color-matrix.frag',
- 'crossfade.frag',
- 'inset-shadow.frag',
- 'linear.frag',
- 'mask.frag',
- 'outset-shadow.frag',
- 'texture.frag',
-]
-
-gsk_private_vulkan_vertex_shaders = [
- 'blendmode.vert',
- 'blur.vert',
- 'border.vert',
- 'color.vert',
- 'color-matrix.vert',
- 'crossfade.vert',
- 'inset-shadow.vert',
- 'linear.vert',
- 'mask.vert',
- 'outset-shadow.vert',
- 'texture.vert',
-]
-
-gsk_private_vulkan_shaders += gsk_private_vulkan_fragment_shaders
-gsk_private_vulkan_shaders += gsk_private_vulkan_vertex_shaders
-
-glslc = find_program('glslc', required: false)
-foreach shader: gsk_private_vulkan_shaders
- basefn = shader.split('.').get(0)
- suffix = shader.split('.').get(1)
-
- stage_arg = suffix == 'frag' ? '-fshader-stage=fragment' : '-fshader-stage=vertex'
- spv_shader = '@0@.@1@.spv'.format(basefn, suffix)
- clip_spv_shader = '@0@-clip.@1@.spv'.format(basefn, suffix)
- clip_rounded_spv_shader = '@0@-clip-rounded.@1@.spv'.format(basefn, suffix)
-
- if glslc.found()
- compiled_shader = custom_target(spv_shader,
- input: shader,
- output: spv_shader,
- command: [
- glslc,
- stage_arg,
- '-DCLIP_NONE',
- '@INPUT@',
- '-o', '@OUTPUT@'
- ])
- compiled_clip_shader = custom_target(clip_spv_shader,
- input: shader,
- output: clip_spv_shader,
- command: [
- glslc,
- stage_arg,
- '-DCLIP_RECT',
- '@INPUT@',
- '-o', '@OUTPUT@'
- ])
- compiled_clip_rounded_shader = custom_target(clip_rounded_spv_shader,
- input: shader,
- output: clip_rounded_spv_shader,
- command: [
- glslc,
- stage_arg,
- '-DCLIP_ROUNDED_RECT',
- '@INPUT@',
- '-o', '@OUTPUT@'
- ])
- gsk_private_vulkan_compiled_shaders_deps += [compiled_shader, compiled_clip_shader, compiled_clip_rounded_shader]
- endif
- gsk_private_vulkan_compiled_shaders += files(spv_shader, clip_spv_shader, clip_rounded_spv_shader)
-endforeach
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-#include "rounded-rect.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in flat vec4 inOutline;
-layout(location = 2) in flat vec4 inOutlineCornerWidths;
-layout(location = 3) in flat vec4 inOutlineCornerHeights;
-layout(location = 4) in flat vec4 inColor;
-layout(location = 5) in flat vec2 inOffset;
-layout(location = 6) in flat float inSpread;
-layout(location = 7) in flat float inBlurRadius;
-
-layout(location = 0) out vec4 color;
-
-void main()
-{
- RoundedRect outline = RoundedRect (vec4(inOutline.xy, inOutline.xy + inOutline.zw), inOutlineCornerWidths, inOutlineCornerHeights);
- RoundedRect outside = rounded_rect_shrink (outline, vec4(-inSpread));
-
- color = vec4(inColor.rgb * inColor.a, inColor.a);
- color = color * clamp (rounded_rect_coverage (outside, inPos - inOffset) -
- rounded_rect_coverage (outline, inPos),
- 0.0, 1.0);
- color = clip (inPos, color);
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inOutline;
-layout(location = 1) in vec4 inOutlineCornerWidths;
-layout(location = 2) in vec4 inOutlineCornerHeights;
-layout(location = 3) in vec4 inColor;
-layout(location = 4) in vec2 inOffset;
-layout(location = 5) in float inSpread;
-layout(location = 6) in float inBlurRadius;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out flat vec4 outOutline;
-layout(location = 2) out flat vec4 outOutlineCornerWidths;
-layout(location = 3) out flat vec4 outOutlineCornerHeights;
-layout(location = 4) out flat vec4 outColor;
-layout(location = 5) out flat vec2 outOffset;
-layout(location = 6) out flat float outSpread;
-layout(location = 7) out flat float outBlurRadius;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-float radius_pixels(float radius) {
- return radius * (3.0 * sqrt(2 * 3.141592653589793) / 4) * 1.5;
-}
-
-void main() {
- vec4 rect = inOutline;
- float spread = inSpread + radius_pixels(inBlurRadius);
- rect += vec4(inOffset - spread, vec2(2 * spread));
-
- clip (inOutline);
-
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
- outPos = pos;
-
- outOutline = inOutline;
- outOutlineCornerWidths = inOutlineCornerWidths;
- outOutlineCornerHeights = inOutlineCornerHeights;
- outColor = inColor;
- outOffset = inOffset;
- outSpread = inSpread;
- outBlurRadius = inBlurRadius;
-}
+++ /dev/null
-#ifndef _ROUNDED_RECT_
-#define _ROUNDED_RECT_
-
-struct RoundedRect
-{
- vec4 bounds;
- vec4 corner_widths;
- vec4 corner_heights;
-};
-
-float
-ellipsis_dist (vec2 p, vec2 radius)
-{
- vec2 p0 = p / radius;
- vec2 p1 = 2.0 * p0 / radius;
-
- return (dot(p0, p0) - 1.0) / length (p1);
-}
-
-float
-ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
-{
- float d = ellipsis_dist (point - center, radius);
- return clamp (0.5 - d, 0.0, 1.0);
-}
-
-float
-rounded_rect_coverage (RoundedRect r, vec2 p)
-{
- if (p.x < r.bounds.x || p.y < r.bounds.y ||
- p.x >= r.bounds.z || p.y >= r.bounds.w)
- return 0.0;
-
- vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
- vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
- vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
- vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
-
- vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
- vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
- vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
- vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
-
- float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
- float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
- float d_br = ellipsis_coverage(p, ref_br, rad_br);
- float d_bl = ellipsis_coverage(p, ref_bl, rad_bl);
-
- vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
-
- bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
- p.x > ref_tr.x && p.y < ref_tr.y,
- p.x > ref_br.x && p.y > ref_br.y,
- p.x < ref_bl.x && p.y > ref_bl.y);
-
- return 1.0 - dot(vec4(is_out), corner_coverages);
-}
-
-RoundedRect
-rounded_rect_shrink (RoundedRect r, vec4 amount)
-{
- vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
- vec4 new_widths = max (r.corner_widths - amount.wyyw, 0.0);
- vec4 new_heights = max (r.corner_heights - amount.xxzz, 0.0);
-
- return RoundedRect (new_bounds, new_widths, new_heights);
-}
-
-#endif
+++ /dev/null
-#version 420 core
-
-#include "clip.frag.glsl"
-
-layout(location = 0) in vec2 inPos;
-layout(location = 1) in vec2 inTexCoord;
-
-layout(set = 0, binding = 0) uniform sampler2D inTexture;
-
-layout(location = 0) out vec4 color;
-
-void main()
-{
- color = clip (inPos, texture (inTexture, inTexCoord));
-}
+++ /dev/null
-#version 420 core
-
-#include "clip.vert.glsl"
-
-layout(location = 0) in vec4 inRect;
-layout(location = 1) in vec4 inTexRect;
-
-layout(location = 0) out vec2 outPos;
-layout(location = 1) out vec2 outTexCoord;
-
-vec2 offsets[6] = { vec2(0.0, 0.0),
- vec2(1.0, 0.0),
- vec2(0.0, 1.0),
- vec2(0.0, 1.0),
- vec2(1.0, 0.0),
- vec2(1.0, 1.0) };
-
-void main() {
- vec4 rect = clip (inRect);
- vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
- gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
-
- outPos = pos;
-
- vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
- rect.zw / inRect.zw);
- texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
- inTexRect.zw * texrect.zw);
- outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
-}
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in vec2 inStartTexCoord;
+layout(location = 2) in vec2 inEndTexCoord;
+layout(location = 3) flat in uint inBlendMode;
+
+layout(set = 0, binding = 0) uniform sampler2D startTexture;
+layout(set = 1, binding = 0) uniform sampler2D endTexture;
+
+layout(location = 0) out vec4 outColor;
+
+float
+combine (float source, float backdrop)
+{
+ return source + backdrop * (1 - source);
+}
+
+vec4
+composite (vec4 Cs, vec4 Cb, vec3 B)
+{
+ float ao = Cs.a + Cb.a * (1 - Cs.a);
+ vec3 Co = (Cs.a*(1 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1 - Cs.a)*Cb.a*Cb.rgb) / ao;
+ return vec4(Co, ao);
+}
+
+vec4
+normal (vec4 Cs, vec4 Cb)
+{
+ return composite (Cs, Cb, Cs.rgb);
+}
+
+vec4
+multiply (vec4 Cs, vec4 Cb)
+{
+ return composite (Cs, Cb, Cs.rgb * Cb.rgb);
+}
+
+vec4
+difference (vec4 Cs, vec4 Cb)
+{
+ return composite (Cs, Cb, abs(Cs.rgb - Cb.rgb));
+}
+
+vec4
+screen (vec4 Cs, vec4 Cb)
+{
+ return composite (Cs, Cb, Cs.rgb + Cb.rgb - Cs.rgb * Cb.rgb);
+}
+
+float
+hard_light (float source, float backdrop)
+{
+ if (source <= 0.5)
+ return 2 * backdrop * source;
+ else
+ return 2 * (backdrop + source - backdrop * source) - 1;
+}
+
+vec4
+hard_light (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (hard_light (Cs.r, Cb.r),
+ hard_light (Cs.g, Cb.g),
+ hard_light (Cs.b, Cb.b));
+ return composite (Cs, Cb, B);
+}
+
+float
+soft_light (float source, float backdrop)
+{
+ float db;
+
+ if (backdrop <= 0.25)
+ db = ((16 * backdrop - 12) * backdrop + 4) * backdrop;
+ else
+ db = sqrt (backdrop);
+
+ if (source <= 0.5)
+ return backdrop - (1 - 2 * source) * backdrop * (1 - backdrop);
+ else
+ return backdrop + (2 * source - 1) * (db - backdrop);
+}
+
+vec4
+soft_light (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (soft_light (Cs.r, Cb.r),
+ soft_light (Cs.g, Cb.g),
+ soft_light (Cs.b, Cb.b));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+overlay (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (hard_light (Cb.r, Cs.r),
+ hard_light (Cb.g, Cs.g),
+ hard_light (Cb.b, Cs.b));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+darken (vec4 Cs, vec4 Cb)
+{
+ vec3 B = min (Cs.rgb, Cb.rgb);
+ return composite (Cs, Cb, B);
+}
+
+vec4
+lighten (vec4 Cs, vec4 Cb)
+{
+ vec3 B = max (Cs.rgb, Cb.rgb);
+ return composite (Cs, Cb, B);
+}
+
+float
+color_dodge (float source, float backdrop)
+{
+ return (source == 1.0) ? source : min (backdrop / (1.0 - source), 1.0);
+}
+
+vec4
+color_dodge (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (color_dodge (Cs.r, Cb.r),
+ color_dodge (Cs.g, Cb.g),
+ color_dodge (Cs.b, Cb.b));
+ return composite (Cs, Cb, B);
+}
+
+
+float
+color_burn (float source, float backdrop)
+{
+ return (source == 0.0) ? source : max ((1.0 - ((1.0 - backdrop) / source)), 0.0);
+}
+
+vec4
+color_burn (vec4 Cs, vec4 Cb)
+{
+ vec3 B = vec3 (color_burn (Cs.r, Cb.r),
+ color_burn (Cs.g, Cb.g),
+ color_burn (Cs.b, Cb.b));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+exclusion (vec4 Cs, vec4 Cb)
+{
+ vec3 B = Cb.rgb + Cs.rgb - 2.0 * Cb.rgb * Cs.rgb;
+ return composite (Cs, Cb, B);
+}
+
+float
+lum (vec3 c)
+{
+ return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
+}
+
+vec3
+clip_color (vec3 c)
+{
+ float l = lum (c);
+ float n = min (c.r, min (c.g, c.b));
+ float x = max (c.r, max (c.g, c.b));
+ if (n < 0) c = l + (((c - l) * l) / (l - n));
+ if (x > 1) c = l + (((c - l) * (1 - l)) / (x - l));
+ return c;
+}
+
+vec3
+set_lum (vec3 c, float l)
+{
+ float d = l - lum (c);
+ return clip_color (vec3 (c.r + d, c.g + d, c.b + d));
+}
+
+float
+sat (vec3 c)
+{
+ return max (c.r, max (c.g, c.b)) - min (c.r, min (c.g, c.b));
+}
+
+vec3
+set_sat (vec3 c, float s)
+{
+ float cmin = min (c.r, min (c.g, c.b));
+ float cmax = max (c.r, max (c.g, c.b));
+ vec3 res;
+
+ if (cmax == cmin)
+ res = vec3 (0, 0, 0);
+ else
+ {
+ if (c.r == cmax)
+ {
+ if (c.g == cmin)
+ {
+ res.b = ((c.b - cmin) * s) / (cmax - cmin);
+ res.g = 0;
+ }
+ else
+ {
+ res.g = ((c.g - cmin) * s) / (cmax - cmin);
+ res.b = 0;
+ }
+ res.r = s;
+ }
+ else if (c.g == cmax)
+ {
+ if (c.r == cmin)
+ {
+ res.b = ((c.b - cmin) * s) / (cmax - cmin);
+ res.r = 0;
+ }
+ else
+ {
+ res.r = ((c.r - cmin) * s) / (cmax - cmin);
+ res.b = 0;
+ }
+ res.g = s;
+ }
+ else
+ {
+ if (c.r == cmin)
+ {
+ res.g = ((c.g - cmin) * s) / (cmax - cmin);
+ res.r = 0;
+ }
+ else
+ {
+ res.r = ((c.r - cmin) * s) / (cmax - cmin);
+ res.g = 0;
+ }
+ res.b = s;
+ }
+ }
+ return res;
+}
+
+vec4
+color (vec4 Cs, vec4 Cb)
+{
+ vec3 B = set_lum (Cs.rgb, lum (Cb.rgb));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+hue (vec4 Cs, vec4 Cb)
+{
+ vec3 B = set_lum (set_sat (Cs.rgb, sat (Cb.rgb)), lum (Cb.rgb));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+saturation (vec4 Cs, vec4 Cb)
+{
+ vec3 B = set_lum (set_sat (Cb.rgb, sat (Cs.rgb)), lum (Cb.rgb));
+ return composite (Cs, Cb, B);
+}
+
+vec4
+luminosity (vec4 Cs, vec4 Cb)
+{
+ vec3 B = set_lum (Cb.rgb, lum (Cs.rgb));
+ return composite (Cs, Cb, B);
+}
+
+void main()
+{
+ vec4 source = texture (startTexture, inStartTexCoord);
+ vec4 backdrop = texture (endTexture, inEndTexCoord);
+ vec4 result;
+
+ if (inBlendMode == 0)
+ result = normal (source, backdrop);
+ else if (inBlendMode == 1)
+ result = multiply (source, backdrop);
+ else if (inBlendMode == 2)
+ result = screen (source, backdrop);
+ else if (inBlendMode == 3)
+ result = overlay (source, backdrop);
+ else if (inBlendMode == 4)
+ result = darken (source, backdrop);
+ else if (inBlendMode == 5)
+ result = lighten (source, backdrop);
+ else if (inBlendMode == 6)
+ result = color_dodge (source, backdrop);
+ else if (inBlendMode == 7)
+ result = color_burn (source, backdrop);
+ else if (inBlendMode == 8)
+ result = hard_light (source, backdrop);
+ else if (inBlendMode == 9)
+ result = soft_light (source, backdrop);
+ else if (inBlendMode == 10)
+ result = difference (source, backdrop);
+ else if (inBlendMode == 11)
+ result = exclusion (source, backdrop);
+ else if (inBlendMode == 12)
+ result = color (source, backdrop);
+ else if (inBlendMode == 13)
+ result = hue (source, backdrop);
+ else if (inBlendMode == 14)
+ result = saturation (source, backdrop);
+ else if (inBlendMode == 15)
+ result = luminosity (source, backdrop);
+ else
+ discard;
+
+ outColor = clip (inPos, result);
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inStartTexRect;
+layout(location = 2) in vec4 inEndTexRect;
+layout(location = 3) in uint inBlendMode;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out vec2 outStartTexCoord;
+layout(location = 2) out vec2 outEndTexCoord;
+layout(location = 3) flat out uint outBlendMode;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+void main() {
+ vec4 rect = clip (inRect);
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+
+ outPos = pos;
+
+ vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
+ rect.zw / inRect.zw);
+ vec4 starttexrect = vec4(inStartTexRect.xy + inStartTexRect.zw * texrect.xy,
+ inStartTexRect.zw * texrect.zw);
+ vec4 endtexrect = vec4(inEndTexRect.xy + inEndTexRect.zw * texrect.xy,
+ inEndTexRect.zw * texrect.zw);
+
+ outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex];
+ outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex];
+
+ outBlendMode = inBlendMode;
+}
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in flat vec2 inSize;
+layout(location = 2) in vec2 inTexCoord;
+layout(location = 3) in float inRadius;
+
+layout(set = 0, binding = 0) uniform sampler2D inTexture;
+
+layout(location = 0) out vec4 color;
+
+const int samples_x = 15; // must be odd
+const int samples_y = 15; // must be odd
+
+const int half_samples_x = samples_x / 2;
+const int half_samples_y = samples_y / 2;
+
+float Gaussian (float sigma, float x)
+{
+ return exp ( - (x * x) / (2.0 * sigma * sigma));
+}
+
+vec4 blur_pixel (in vec2 uv)
+{
+ float total = 0.0;
+ vec4 ret = vec4 (0);
+ float pixel_size_x = (1.0 / inSize.x);
+ float pixel_size_y = (1.0 / inSize.y);
+
+ for (int y = 0; y < samples_y; ++y)
+ {
+ float fy = Gaussian (inRadius, float(y) - float(half_samples_x));
+ float offset_y = float(y - half_samples_y) * pixel_size_y;
+ for (int x = 0; x < samples_x; ++x)
+ {
+ float fx = Gaussian (inRadius, float(x) - float(half_samples_x));
+ float offset_x = float(x - half_samples_x) * pixel_size_x;
+ total += fx * fy;
+ ret += texture(inTexture, uv + vec2(offset_x, offset_y)) * fx * fy;
+ }
+ }
+ return ret / total;
+}
+
+void main()
+{
+ color = clip (inPos, blur_pixel (inTexCoord));
+}
--- /dev/null
+
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inTexRect;
+layout(location = 2) in float inRadius;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out flat vec2 outSize;
+layout(location = 2) out vec2 outTexCoord;
+layout(location = 3) out flat float outRadius;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+void main() {
+ vec4 rect = clip (inRect);
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+
+ outPos = pos;
+ outSize = inRect.zw;
+
+ vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
+ rect.zw / inRect.zw);
+ texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
+ inTexRect.zw * texrect.zw);
+ outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
+
+ outRadius = inRadius;
+}
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+#include "rounded-rect.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in vec4 inColor;
+layout(location = 2) in vec4 inRect;
+layout(location = 3) in vec4 inCornerWidths;
+layout(location = 4) in vec4 inCornerHeights;
+layout(location = 5) in vec4 inBorderWidths;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ RoundedRect routside = RoundedRect (vec4(inRect.xy, inRect.xy + inRect.zw), inCornerWidths, inCornerHeights);
+ RoundedRect rinside = rounded_rect_shrink (routside, inBorderWidths);
+
+ float alpha = clamp (rounded_rect_coverage (routside, inPos) -
+ rounded_rect_coverage (rinside, inPos),
+ 0.0, 1.0);
+ color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a) * alpha);
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inCornerWidths;
+layout(location = 2) in vec4 inCornerHeights;
+layout(location = 3) in vec4 inBorderWidths;
+layout(location = 4) in mat4 inBorderColors;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out flat vec4 outColor;
+layout(location = 2) out flat vec4 outRect;
+layout(location = 3) out flat vec4 outCornerWidths;
+layout(location = 4) out flat vec4 outCornerHeights;
+layout(location = 5) out flat vec4 outBorderWidths;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0) };
+
+#define TOP 0
+#define RIGHT 1
+#define BOTTOM 2
+#define LEFT 3
+
+#define TOP_LEFT 0
+#define TOP_RIGHT 1
+#define BOTTOM_RIGHT 2
+#define BOTTOM_LEFT 3
+
+#define SLICE_TOP_LEFT 0
+#define SLICE_TOP 1
+#define SLICE_TOP_RIGHT 2
+#define SLICE_RIGHT 3
+#define SLICE_BOTTOM_RIGHT 4
+#define SLICE_BOTTOM 5
+#define SLICE_BOTTOM_LEFT 6
+#define SLICE_LEFT 7
+
+void main() {
+ int slice_index = gl_VertexIndex / 6;
+ int vert_index = gl_VertexIndex % 6;
+
+ vec4 corner_widths = max (inCornerWidths, inBorderWidths.wyyw);
+ vec4 corner_heights = max (inCornerHeights, inBorderWidths.xxzz);
+
+ vec4 rect;
+
+ switch (slice_index)
+ {
+ case SLICE_TOP_LEFT:
+ rect = vec4(inRect.xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]);
+ vert_index = (vert_index + 3) % 6;
+ break;
+ case SLICE_TOP:
+ rect = vec4(inRect.x + corner_widths[TOP_LEFT], inRect.y, inRect.z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[TOP]);
+ outColor = inBorderColors[TOP];
+ break;
+ case SLICE_TOP_RIGHT:
+ rect = vec4(inRect.x + inRect.z - corner_widths[TOP_RIGHT], inRect.y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]);
+ break;
+ case SLICE_RIGHT:
+ rect = vec4(inRect.x + inRect.z - inBorderWidths[RIGHT], inRect.y + corner_heights[TOP_RIGHT], inBorderWidths[RIGHT], inRect.w - corner_heights[TOP_RIGHT] - corner_heights[BOTTOM_RIGHT]);
+ outColor = inBorderColors[RIGHT];
+ break;
+ case SLICE_BOTTOM_RIGHT:
+ rect = vec4(inRect.x + inRect.z - corner_widths[BOTTOM_RIGHT], inRect.y + inRect.w - corner_heights[BOTTOM_RIGHT], corner_widths[BOTTOM_RIGHT], corner_heights[BOTTOM_RIGHT]);
+ break;
+ case SLICE_BOTTOM:
+ rect = vec4(inRect.x + corner_widths[BOTTOM_LEFT], inRect.y + inRect.w - inBorderWidths[BOTTOM], inRect.z - corner_widths[BOTTOM_LEFT] - corner_widths[BOTTOM_RIGHT], inBorderWidths[BOTTOM]);
+ break;
+ case SLICE_BOTTOM_LEFT:
+ rect = vec4(inRect.x, inRect.y + inRect.w - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], corner_heights[BOTTOM_LEFT]);
+ vert_index = (vert_index + 3) % 6;
+ break;
+ case SLICE_LEFT:
+ rect = vec4(inRect.x, inRect.y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect.w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_LEFT]);
+ break;
+ }
+
+ rect = clip (rect);
+ vec2 pos;
+ if ((slice_index % 4) != 0 || (vert_index % 3) != 2)
+ pos = rect.xy + rect.zw * offsets[vert_index];
+ else
+ pos = rect.xy + rect.zw * vec2(1.0 - offsets[vert_index].x, offsets[vert_index].y);
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+ outColor = inBorderColors[((gl_VertexIndex / 3 + 15) / 4) % 4];
+ outPos = pos;
+ outRect = inRect;
+ outCornerWidths = inCornerWidths;
+ outCornerHeights = inCornerHeights;
+ outBorderWidths = inBorderWidths;
+}
--- /dev/null
+#include "constants.glsl"
+#include "rounded-rect.glsl"
+
+#ifndef _CLIP_
+#define _CLIP_
+
+#ifdef CLIP_ROUNDED_RECT
+vec4 clip(vec2 pos, vec4 color)
+{
+ RoundedRect r = RoundedRect(vec4(push.clip_bounds.xy, push.clip_bounds.xy + push.clip_bounds.zw), push.clip_widths, push.clip_heights);
+
+ return color * rounded_rect_coverage (r, pos);
+}
+#elif defined(CLIP_RECT)
+vec4 clip(vec2 pos, vec4 color)
+{
+ /* clipped in vertex shader already */
+ return color;
+}
+#elif defined(CLIP_NONE)
+vec4 clip(vec2 pos, vec4 color)
+{
+ return color;
+}
+#else
+#error "No clipping define given. Need CLIP_NONE, CLIP_RECT or CLIP_ROUNDED_RECT"
+#endif
+
+#endif
--- /dev/null
+#include "constants.glsl"
+
+#ifndef _CLIP_
+#define _CLIP_
+
+vec4 intersect(vec4 a, vec4 b)
+{
+ a = vec4(a.xy, a.xy + a.zw);
+ b = vec4(b.xy, b.xy + b.zw);
+ vec4 result = vec4(max(a.xy, b.xy), min(a.zw, b.zw));
+ if (any (greaterThanEqual (result.xy, result.zw)))
+ return vec4(0.0,0.0,0.0,0.0);
+ return vec4(result.xy, result.zw - result.xy);
+}
+
+#ifdef CLIP_ROUNDED_RECT
+vec4 clip(vec4 rect)
+{
+ /* rounded corner clipping is done in fragment shader */
+ return intersect(rect, push.clip_bounds);
+}
+#elif defined(CLIP_RECT)
+vec4 clip(vec4 rect)
+{
+ return intersect(rect, push.clip_bounds);
+}
+#elif defined(CLIP_NONE)
+vec4 clip(vec4 rect)
+{
+ return rect;
+}
+#else
+#error "No clipping define given. Need CLIP_NONE, CLIP_RECT or CLIP_ROUNDED_RECT"
+#endif
+
+#endif
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in vec2 inTexCoord;
+layout(location = 2) in flat mat4 inColorMatrix;
+layout(location = 6) in flat vec4 inColorOffset;
+
+layout(set = 0, binding = 0) uniform sampler2D inTexture;
+
+layout(location = 0) out vec4 color;
+
+vec4
+color_matrix (vec4 color, mat4 color_matrix, vec4 color_offset)
+{
+ /* unpremultiply */
+ if (color.a != 0.0)
+ color.rgb /= color.a;
+
+ color = color_matrix * color + color_offset;
+ color = clamp(color, 0.0, 1.0);
+
+ /* premultiply */
+ color.rgb *= color.a;
+
+ return color;
+}
+
+void main()
+{
+ color = clip (inPos, color_matrix (texture (inTexture, inTexCoord), inColorMatrix, inColorOffset));
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inTexRect;
+layout(location = 2) in mat4 inColorMatrix;
+layout(location = 6) in vec4 inColorOffset;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out vec2 outTexCoord;
+layout(location = 2) out flat mat4 outColorMatrix;
+layout(location = 6) out flat vec4 outColorOffset;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+void main() {
+ vec4 rect = clip (inRect);
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+
+ outPos = pos;
+
+ vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
+ rect.zw / inRect.zw);
+ texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
+ inTexRect.zw * texrect.zw);
+ outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
+ outColorMatrix = inColorMatrix;
+ outColorOffset = inColorOffset;
+}
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in vec4 inColor;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a));
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inColor;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out flat vec4 outColor;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+void main() {
+ vec4 rect = clip (inRect);
+
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+ outPos = pos;
+ outColor = inColor;
+}
--- /dev/null
+#ifndef _CONSTANTS_
+#define _CONSTANTS_
+
+layout(push_constant) uniform PushConstants {
+ mat4 mvp;
+ vec4 clip_bounds;
+ vec4 clip_widths;
+ vec4 clip_heights;
+} push;
+
+#endif
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in vec2 inStartTexCoord;
+layout(location = 2) in vec2 inEndTexCoord;
+layout(location = 3) in float inProgress;
+
+layout(set = 0, binding = 0) uniform sampler2D startTexture;
+layout(set = 1, binding = 0) uniform sampler2D endTexture;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ vec4 start = texture (startTexture, inStartTexCoord);
+ vec4 end = texture (endTexture, inEndTexCoord);
+
+ color = clip (inPos, mix (start, end, inProgress));
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inStartTexRect;
+layout(location = 2) in vec4 inEndTexRect;
+layout(location = 3) in float inProgress;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out vec2 outStartTexCoord;
+layout(location = 2) out vec2 outEndTexCoord;
+layout(location = 3) out float outProgress;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+void main() {
+ vec4 rect = clip (inRect);
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+
+ outPos = pos;
+
+ vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
+ rect.zw / inRect.zw);
+ vec4 starttexrect = vec4(inStartTexRect.xy + inStartTexRect.zw * texrect.xy,
+ inStartTexRect.zw * texrect.zw);
+ vec4 endtexrect = vec4(inEndTexRect.xy + inEndTexRect.zw * texrect.xy,
+ inEndTexRect.zw * texrect.zw);
+
+ outStartTexCoord = starttexrect.xy + starttexrect.zw * offsets[gl_VertexIndex];
+ outEndTexCoord = endtexrect.xy + endtexrect.zw * offsets[gl_VertexIndex];
+
+ outProgress = inProgress;
+}
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+#include "rounded-rect.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in flat vec4 inOutline;
+layout(location = 2) in flat vec4 inOutlineCornerWidths;
+layout(location = 3) in flat vec4 inOutlineCornerHeights;
+layout(location = 4) in flat vec4 inColor;
+layout(location = 5) in flat vec2 inOffset;
+layout(location = 6) in flat float inSpread;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ RoundedRect outline = RoundedRect (vec4(inOutline.xy, inOutline.xy + inOutline.zw), inOutlineCornerWidths, inOutlineCornerHeights);
+ RoundedRect inside = rounded_rect_shrink (outline, vec4(inSpread));
+
+ color = vec4(inColor.rgb * inColor.a, inColor.a);
+ color = color * clamp (rounded_rect_coverage (outline, inPos) -
+ rounded_rect_coverage (inside, inPos - inOffset),
+ 0.0, 1.0);
+ color = clip (inPos, color);
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inOutline;
+layout(location = 1) in vec4 inOutlineCornerWidths;
+layout(location = 2) in vec4 inOutlineCornerHeights;
+layout(location = 3) in vec4 inColor;
+layout(location = 4) in vec2 inOffset;
+layout(location = 5) in float inSpread;
+layout(location = 6) in float inBlurRadius;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out flat vec4 outOutline;
+layout(location = 2) out flat vec4 outOutlineCornerWidths;
+layout(location = 3) out flat vec4 outOutlineCornerHeights;
+layout(location = 4) out flat vec4 outColor;
+layout(location = 5) out flat vec2 outOffset;
+layout(location = 6) out flat float outSpread;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+void main() {
+ vec4 rect = clip (inOutline);
+
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+ outPos = pos;
+
+ outOutline = inOutline;
+ outOutlineCornerWidths = inOutlineCornerWidths;
+ outOutlineCornerHeights = inOutlineCornerHeights;
+ outColor = inColor;
+ outOffset = inOffset;
+ outSpread = inSpread;
+}
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+
+struct ColorStop {
+ float offset;
+ vec4 color;
+};
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in float inGradientPos;
+layout(location = 2) in flat int inRepeating;
+layout(location = 3) in flat int inStopCount;
+layout(location = 4) in flat ColorStop inStops[8];
+
+layout(location = 0) out vec4 outColor;
+
+void main()
+{
+ float pos;
+ if (inRepeating != 0)
+ pos = fract (inGradientPos);
+ else
+ pos = clamp (inGradientPos, 0, 1);
+
+ vec4 color = inStops[0].color;
+ int n = clamp (inStopCount, 2, 8);
+ for (int i = 1; i < n; i++)
+ {
+ if (inStops[i].offset > inStops[i-1].offset)
+ color = mix (color, inStops[i].color, clamp((pos - inStops[i-1].offset) / (inStops[i].offset - inStops[i-1].offset), 0, 1));
+ }
+
+ //outColor = vec4(pos, pos, pos, 1.0);
+ outColor = clip (inPos, color);
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+struct ColorStop {
+ float offset;
+ vec4 color;
+};
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec2 inStart;
+layout(location = 2) in vec2 inEnd;
+layout(location = 3) in int inRepeating;
+layout(location = 4) in int inStopCount;
+layout(location = 5) in vec4 inOffsets0;
+layout(location = 6) in vec4 inOffsets1;
+layout(location = 7) in vec4 inColors0;
+layout(location = 8) in vec4 inColors1;
+layout(location = 9) in vec4 inColors2;
+layout(location = 10) in vec4 inColors3;
+layout(location = 11) in vec4 inColors4;
+layout(location = 12) in vec4 inColors5;
+layout(location = 13) in vec4 inColors6;
+layout(location = 14) in vec4 inColors7;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out float outGradientPos;
+layout(location = 2) out flat int outRepeating;
+layout(location = 3) out flat int outStopCount;
+layout(location = 4) out flat ColorStop outStops[8];
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+float
+get_gradient_pos (vec2 pos)
+{
+ pos = pos - inStart;
+ vec2 grad = inEnd - inStart;
+
+ return dot (pos, grad) / dot (grad, grad);
+}
+
+void main() {
+ vec4 rect = clip (inRect);
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+ outPos = pos;
+ outGradientPos = get_gradient_pos (pos);
+ outRepeating = inRepeating;
+ outStopCount = inStopCount;
+ outStops[0].offset = inOffsets0[0];
+ outStops[0].color = inColors0 * vec4(inColors0.aaa, 1.0);
+ outStops[1].offset = inOffsets0[1];
+ outStops[1].color = inColors1 * vec4(inColors1.aaa, 1.0);
+ outStops[2].offset = inOffsets0[2];
+ outStops[2].color = inColors2 * vec4(inColors2.aaa, 1.0);
+ outStops[3].offset = inOffsets0[3];
+ outStops[3].color = inColors3 * vec4(inColors3.aaa, 1.0);
+ outStops[4].offset = inOffsets1[0];
+ outStops[4].color = inColors4 * vec4(inColors4.aaa, 1.0);
+ outStops[5].offset = inOffsets1[1];
+ outStops[5].color = inColors5 * vec4(inColors5.aaa, 1.0);
+ outStops[6].offset = inOffsets1[2];
+ outStops[6].color = inColors6 * vec4(inColors6.aaa, 1.0);
+ outStops[7].offset = inOffsets1[3];
+ outStops[7].color = inColors7 * vec4(inColors7.aaa, 1.0);
+}
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in vec2 inTexCoord;
+layout(location = 2) in vec4 inColor;
+
+layout(set = 0, binding = 0) uniform sampler2D inTexture;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a) * texture(inTexture, inTexCoord).a);
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inTexRect;
+layout(location = 2) in vec4 inColor;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out vec2 outTexCoord;
+layout(location = 2) out flat vec4 outColor;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+void main() {
+ vec4 rect = clip (inRect);
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+
+ outPos = pos;
+
+ vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
+ rect.zw / inRect.zw);
+ texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
+ inTexRect.zw * texrect.zw);
+ outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
+
+ outColor = inColor;
+}
--- /dev/null
+# FIXME: what's up with these?
+#gsk_private_vulkan_include_shaders = [
+# 'clip.frag.glsl',
+# 'clip.vert.glsl',
+# 'constants.glsl',
+# 'rounded-rect.glsl',
+#]
+
+gsk_private_vulkan_fragment_shaders = [
+ 'blendmode.frag',
+ 'blur.frag',
+ 'border.frag',
+ 'color.frag',
+ 'color-matrix.frag',
+ 'crossfade.frag',
+ 'inset-shadow.frag',
+ 'linear.frag',
+ 'mask.frag',
+ 'outset-shadow.frag',
+ 'texture.frag',
+]
+
+gsk_private_vulkan_vertex_shaders = [
+ 'blendmode.vert',
+ 'blur.vert',
+ 'border.vert',
+ 'color.vert',
+ 'color-matrix.vert',
+ 'crossfade.vert',
+ 'inset-shadow.vert',
+ 'linear.vert',
+ 'mask.vert',
+ 'outset-shadow.vert',
+ 'texture.vert',
+]
+
+gsk_private_vulkan_shaders += gsk_private_vulkan_fragment_shaders
+gsk_private_vulkan_shaders += gsk_private_vulkan_vertex_shaders
+
+glslc = find_program('glslc', required: false)
+foreach shader: gsk_private_vulkan_shaders
+ basefn = shader.split('.').get(0)
+ suffix = shader.split('.').get(1)
+
+ stage_arg = suffix == 'frag' ? '-fshader-stage=fragment' : '-fshader-stage=vertex'
+ spv_shader = '@0@.@1@.spv'.format(basefn, suffix)
+ clip_spv_shader = '@0@-clip.@1@.spv'.format(basefn, suffix)
+ clip_rounded_spv_shader = '@0@-clip-rounded.@1@.spv'.format(basefn, suffix)
+
+ if glslc.found()
+ compiled_shader = custom_target(spv_shader,
+ input: shader,
+ output: spv_shader,
+ command: [
+ glslc,
+ stage_arg,
+ '-DCLIP_NONE',
+ '@INPUT@',
+ '-o', '@OUTPUT@'
+ ])
+ compiled_clip_shader = custom_target(clip_spv_shader,
+ input: shader,
+ output: clip_spv_shader,
+ command: [
+ glslc,
+ stage_arg,
+ '-DCLIP_RECT',
+ '@INPUT@',
+ '-o', '@OUTPUT@'
+ ])
+ compiled_clip_rounded_shader = custom_target(clip_rounded_spv_shader,
+ input: shader,
+ output: clip_rounded_spv_shader,
+ command: [
+ glslc,
+ stage_arg,
+ '-DCLIP_ROUNDED_RECT',
+ '@INPUT@',
+ '-o', '@OUTPUT@'
+ ])
+ gsk_private_vulkan_compiled_shaders_deps += [compiled_shader, compiled_clip_shader, compiled_clip_rounded_shader]
+ endif
+ gsk_private_vulkan_compiled_shaders += files(spv_shader, clip_spv_shader, clip_rounded_spv_shader)
+endforeach
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+#include "rounded-rect.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in flat vec4 inOutline;
+layout(location = 2) in flat vec4 inOutlineCornerWidths;
+layout(location = 3) in flat vec4 inOutlineCornerHeights;
+layout(location = 4) in flat vec4 inColor;
+layout(location = 5) in flat vec2 inOffset;
+layout(location = 6) in flat float inSpread;
+layout(location = 7) in flat float inBlurRadius;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ RoundedRect outline = RoundedRect (vec4(inOutline.xy, inOutline.xy + inOutline.zw), inOutlineCornerWidths, inOutlineCornerHeights);
+ RoundedRect outside = rounded_rect_shrink (outline, vec4(-inSpread));
+
+ color = vec4(inColor.rgb * inColor.a, inColor.a);
+ color = color * clamp (rounded_rect_coverage (outside, inPos - inOffset) -
+ rounded_rect_coverage (outline, inPos),
+ 0.0, 1.0);
+ color = clip (inPos, color);
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inOutline;
+layout(location = 1) in vec4 inOutlineCornerWidths;
+layout(location = 2) in vec4 inOutlineCornerHeights;
+layout(location = 3) in vec4 inColor;
+layout(location = 4) in vec2 inOffset;
+layout(location = 5) in float inSpread;
+layout(location = 6) in float inBlurRadius;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out flat vec4 outOutline;
+layout(location = 2) out flat vec4 outOutlineCornerWidths;
+layout(location = 3) out flat vec4 outOutlineCornerHeights;
+layout(location = 4) out flat vec4 outColor;
+layout(location = 5) out flat vec2 outOffset;
+layout(location = 6) out flat float outSpread;
+layout(location = 7) out flat float outBlurRadius;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+float radius_pixels(float radius) {
+ return radius * (3.0 * sqrt(2 * 3.141592653589793) / 4) * 1.5;
+}
+
+void main() {
+ vec4 rect = inOutline;
+ float spread = inSpread + radius_pixels(inBlurRadius);
+ rect += vec4(inOffset - spread, vec2(2 * spread));
+
+ clip (inOutline);
+
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+ outPos = pos;
+
+ outOutline = inOutline;
+ outOutlineCornerWidths = inOutlineCornerWidths;
+ outOutlineCornerHeights = inOutlineCornerHeights;
+ outColor = inColor;
+ outOffset = inOffset;
+ outSpread = inSpread;
+ outBlurRadius = inBlurRadius;
+}
--- /dev/null
+#ifndef _ROUNDED_RECT_
+#define _ROUNDED_RECT_
+
+struct RoundedRect
+{
+ vec4 bounds;
+ vec4 corner_widths;
+ vec4 corner_heights;
+};
+
+float
+ellipsis_dist (vec2 p, vec2 radius)
+{
+ vec2 p0 = p / radius;
+ vec2 p1 = 2.0 * p0 / radius;
+
+ return (dot(p0, p0) - 1.0) / length (p1);
+}
+
+float
+ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
+{
+ float d = ellipsis_dist (point - center, radius);
+ return clamp (0.5 - d, 0.0, 1.0);
+}
+
+float
+rounded_rect_coverage (RoundedRect r, vec2 p)
+{
+ if (p.x < r.bounds.x || p.y < r.bounds.y ||
+ p.x >= r.bounds.z || p.y >= r.bounds.w)
+ return 0.0;
+
+ vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
+ vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
+ vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
+ vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
+
+ vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
+ vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
+ vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
+ vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
+
+ float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
+ float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
+ float d_br = ellipsis_coverage(p, ref_br, rad_br);
+ float d_bl = ellipsis_coverage(p, ref_bl, rad_bl);
+
+ vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
+
+ bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
+ p.x > ref_tr.x && p.y < ref_tr.y,
+ p.x > ref_br.x && p.y > ref_br.y,
+ p.x < ref_bl.x && p.y > ref_bl.y);
+
+ return 1.0 - dot(vec4(is_out), corner_coverages);
+}
+
+RoundedRect
+rounded_rect_shrink (RoundedRect r, vec4 amount)
+{
+ vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
+ vec4 new_widths = max (r.corner_widths - amount.wyyw, 0.0);
+ vec4 new_heights = max (r.corner_heights - amount.xxzz, 0.0);
+
+ return RoundedRect (new_bounds, new_widths, new_heights);
+}
+
+#endif
--- /dev/null
+#version 420 core
+
+#include "clip.frag.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in vec2 inTexCoord;
+
+layout(set = 0, binding = 0) uniform sampler2D inTexture;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ color = clip (inPos, texture (inTexture, inTexCoord));
+}
--- /dev/null
+#version 420 core
+
+#include "clip.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inTexRect;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out vec2 outTexCoord;
+
+vec2 offsets[6] = { vec2(0.0, 0.0),
+ vec2(1.0, 0.0),
+ vec2(0.0, 1.0),
+ vec2(0.0, 1.0),
+ vec2(1.0, 0.0),
+ vec2(1.0, 1.0) };
+
+void main() {
+ vec4 rect = clip (inRect);
+ vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex];
+ gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
+
+ outPos = pos;
+
+ vec4 texrect = vec4((rect.xy - inRect.xy) / inRect.zw,
+ rect.zw / inRect.zw);
+ texrect = vec4(inTexRect.xy + inTexRect.zw * texrect.xy,
+ inTexRect.zw * texrect.zw);
+ outTexCoord = texrect.xy + texrect.zw * offsets[gl_VertexIndex];
+}